有一个小系统,在MSSQL2005上有一个数据库表作为队列。有几个应用程序正在向该表写入数据,其中一个应用程序正在以FIFO方式读取和处理数据。
我必须让它更先进一点,才能创建一个分布式系统,在其中可以运行多个处理应用程序。结果应该是2-10处理应用程序应该能够运行,并且它们在工作期间不应该相互干扰。
我的想法是用一行来扩展队列表,该行显示进程已经在处理它。处理应用程序将首先用它的idetifyer更新表,然后请求更新的记录。
所以就像这样:
start transaction
update top(10) queue set processing = 'myid' where processing is null
select * from processing where processing = 'myid'
end transaction在处理之后,它将表的processing列设置为其他值,如'done‘或其他值。
关于这种方法,我有三个问题。
首先:这种形式可以工作吗?
第二:如果它是有效的,它是否有效?你有没有其他的想法来创建这样的发行版?
第三:在MSSQL中,锁定是基于行的,但是在锁定一定数量的行之后,锁将扩展到整个表。因此,在第一个应用程序不释放事务之前,第二个应用程序无法访问它。为了不锁定整个表格,只创建行锁定,选择(top x)可以有多大?
发布于 2008-10-30 09:05:28
这是可行的,但您可能会发现遇到阻塞或死锁,多个进程尝试读取/更新相同的数据。我为我们的一个系统写了一个过程来做这件事,它使用了一些有趣的锁定语义来确保这种类型的东西运行时没有阻塞或死锁,described here。
发布于 2008-10-30 08:54:15
这种方法在我看来是合理的,并且与我过去使用的方法类似-成功。
此外,行/表只有在更新和选择操作发生时才会被锁定,所以我怀疑行与表的问题是否真的是一个主要考虑因素。
除非你的应用程序的处理开销低到可以忽略不计,否则我会保持"top“值很低--可能只有1。当然,这完全取决于你的应用程序的细节。
话虽如此,我不是DBA,因此我也会对更多的专家答案感兴趣
发布于 2008-10-30 09:46:02
关于你关于锁定的问题。您可以使用锁定提示强制它仅锁定行
update mytable with (rowlock) set x=y where a=bhttps://stackoverflow.com/questions/249573
复制相似问题