SQL Server和消息队列

时间:2009-04-25 08:51:39

标签: c# sql sql-server

我正在尝试构建一个可靠的消息服务,或者至少我会如何描述它。

这是我的问题:我有一个表,我在这个表中插入数据,我至少有两个应用程序从这个表中选择数据。但是,我需要一种可靠的方法让两个不同的应用程序永远不会在任何给定的时间选择相同的行。

我如何编写一个事务或select语句,保证不会选择与其他应用程序最近选择的行相同的行。

我不是SQL Server专家,但我希望能有类似的东西。

从表中选择工作,这将为应用程序提供对某些行的独占访问权限。然后,应用程序将处理这些行。某些行被删除,一些行被返回到数据库。

我主要担心的是,如果应用程序无法完成处理,SQL Server最终会超时并将签出的数据返回给应用程序数据池。

4 个答案:

答案 0 :(得分:6)

为每条记录添加一个“正在处理”标志,该记录以“原子”方式设置。

这里有几个问题和许多答案,与此类似:

How do I lock certain SQL rows while running a process on them?

Queues against Tables in messaging systems

What’s the best way of implementing a messaging queue table in mysql

Posting Message to MSMQ from SQL Server

答案 1 :(得分:3)

这是一个相当古老的问题,可能作者的问题现在已经很久了,但是有一些SQL技巧可以解决它并对其他人有用:'readpast'提示。 使用readpast sql select将跳过查询中的锁定行。你想要的是抓住第一个未锁定的行并立即将其锁定,这样其他任何人都无法获得它:

从id

的(readpast,updlock)顺序的消息中选择前1 *
  • 这将选择并锁定表中的第一个空闲消息,因此没有其他人能够修改它。实际上我在基于SQL的消息总线中使用相同的方法:http://http://code.google.com/p/nginn-messagebus/并且它工作非常顺利(有时比MSMQ更快)

答案 2 :(得分:2)

看看SQL Server Service Broker,它专为此类问题而设计。

如果您需要队列,请使用队列。

答案 3 :(得分:0)

在“消息”表中添加“抓取”列。每个人都可以尝试使用单个SQL语句获取一行:

UPDATE m
SET grabbed = 1
FROM messages m
WHERE id = @myid
and grabbed = 0

在此之后,如果@@ ROWCOUNT为1,则该行是您的。否则,别人就会抢到你之前的那一行。

SQL Server Broker或MSMQ或MQSeries引入了大量复杂性和维护开销。在开始使用之前,请确保收到你的东西的操作人员同意。