2011-03-01 52 views
1

经典的生产者 - 消费者问题。使用SQL Server和ASP.NET的生产者 - 消费者问题

我有x个应用程序服务器在DB表(相同的数据库)中写入记录。

在每台服务器上运行一个服务,该服务轮询数据库表,应该读取最旧的条目,处理它并删除它。 现在的问题是服务进入竞争状态:服务器A上的服务开始读取,服务器B开始读取相同的记录。我有点卡住这个......我经常实施生产者 - 消费者,但从来没有跨越服务器壁垒。

除了在数据库之外,服务器不能相互通话。

环境是SQL Server 2005和ASP-NET 3.5。

+0

如何在表中添加处理标志以有效锁定行,以便在特定服务器正在处理该行时进行处理。 – Andrew 2011-03-01 07:56:55

回答

4

如果你在一个事务性的方式拿起工作,只有一台服务器可以把它捡起来:

set transaction isolation level repeatable read 

update top 1 tbl 
set  ProcessingOnServer = HOST_NAME() 
from YourWorkTable tbl 
where ProcessingOnServer is null 
     and Done = 0 

现在您可以选择的细节,知道工作项被安全地分配给你:

select * 
from YourWorkTable tbl 
where ProcessingOnServer = HOST_NAME() 
     and Done = 0 

函数host_name()返回客户端名称,但如果您认为它更安全,则可以从客户端应用程序传入主机名。

我们通常会添加一个时间戳,以便您可以检查花费太长时间处理项目的服务器。

+0

但是,如果不事先更新并直接读取,那么是否就足以“设置事务隔离级别可重复读取”? – Krumelur 2011-03-01 08:08:55

+0

@Krumelur:嗯不,因为其他进程可以同时读取。事务以'begin transaction'开始,但在实际读取或写入表之前它仍不会获取锁。 – Andomar 2011-03-01 14:24:37

+0

我不明白。在你的例子中,我没有看到“开始交易”...? – Krumelur 2011-03-01 21:01:36