2011-04-05 71 views
1

我有一个传入的消息队列在SQL数据库(当前MS SQL Server)中实现,可通过Web服务访问。此Web服务运行遗留协议我们无法控制,并且必须返回一个“没有消息队列的回应,或两者:在队列 并发问题与数据库队列,需要便携式解决方案

  • 的其他数最古老的消息

    • 详细在队列

    用于此算法的消息是目前非常粗糙:

    1. 在队列中选择所有的消息
    2. 剩余的消息数=行数 - 1个
    3. 更新最古老的消息,集采集标志

    我们正在向那里这个现在可以同时访问的情况,并已明显遇到并发问题在同一消息被拾取两次。

    我们遇到的问题是,我们需要一个便携式解决方案最低部署要求。理想情况下,这意味着没有存储过程,并且没有引擎专用锁。

    有没有人有任何明智的想法?

    谢谢!

  • 回答

    1

    最终,给你描述的限制,出列必须做一个消息 - 然而,与向数据库事务(所有Web服务处理代码,网络和HTTP延迟)传递消息有关的更多。

    当前的系统在事务控制方面并没有明显的实现 - 所以我认为这对于并发解决方案也不是问题。

    如果是我,我会设置一个存储过程(为什么你认为它们不可移植?)与具有可序列化锁的事务中的操作 - 我还会缓存队列消息的数量基于缓存值的操作次数/年龄的TTL,以减少基础表上代价高昂的聚合操作的数量。这可以通过从controllnig语言一次发布DML操作来完成 - 但最终结果是操作将花费更长的时间。

    另一种方法(使实现锁定更容易)将分片数据 - 不确定MSSQL是否支持命名锁 - 当然它不是一个非常便携的解决方案 - 因此将数据拆分为单独的表和使用表锁。这使得实现事务控制变得简单很多 - 但是在装载/内部处理/顺序处理方面存在问题(但同样的方法适用于后者并不是一个大问题)。

    +0

    我会假设存储过程不可移植,因为不是所有的数据库都有它们......如果它们端口到另一个数据库解决方案它不会工作。 – 2011-04-05 16:24:10

    +0

    基本上是的 - 我们担心这个功能在另一个SQL引擎上不可用,并且增加了部署需求的复杂性。 – spronkey 2011-04-06 10:11:40

    2

    由于您已经在使用SQL Server,因此您应该使用SQL Server Service Broker进行调查。

    但是这关系到你的SQL Server ...

    有一件事你可以考虑为你做一个选择......让行ID ...将行更新标记为与新的ROWID收集(guid或类似的东西),你生成的...选择它再次...如果行ID是你设置的那个,那么你是谁得到它......如果没有人在你之前进来,你必须得到去另一个。

    基本上你是自己实现脏读保护......因为你不想使用事务或存储过程...

    +0

    实际上更正...您应该更新rowID,其中ROWID仍然与您得到的相同......然后您可以使用更新的行数(行数)或再次选择该事件以查看是否你先得到它...正如我原来说的那样...你仍然可以得到协调问题... – 2011-04-05 02:41:49