有一个小型系统,其中数据库表作为MSSQL 2005上的队列。有几个应用程序正在写入此表,一个应用程序正在以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

处理完毕后,它会将表格的处理列设置为其他内容,例如“已完成”或其他任何内容。

我对这种方法有三个问题。

首先:这可以用这种形式吗?

第二:如果它有效,它有效吗?你有任何其他想法来创建这样的发行版吗?

第三:在MSSQL中,锁定是基于行的,但是在锁定了一定数量的行之后,锁定会扩展到整个表。因此,在第一个应用程序未释放事务之前,第二个应用程序无法访问它。选择有多大(顶部x)以便不锁定整个表,只创建行锁?

有帮助吗?

解决方案

这样可行,但您可能会发现在多个进程尝试读取/更新相同数据时会遇到阻塞或死锁。我为我们的一个系统编写了一个程序,它使用一些有趣的锁定语义来确保这种类型的东西在没有阻塞或死锁的情况下运行,这里描述

其他提示

这种方法对我来说看起来很合理,并且与我过去使用的方法类似 - 成功。

此外,只有在更新和选择操作发生时才会锁定行/表,因此我怀疑行与表问题是否是一个主要考虑因素。

除非你的应用程序的处理开销太低而且可以忽略不计,否则我会保留“顶部”。价值低 - 也许只是1.当然,这完全取决于你的应用程序的细节。

说了这么多,我不是DBA,所以也会对任何更专业的答案感兴趣

关于你的锁定问题。您可以使用锁定提示强制它仅锁定行

update mytable with (rowlock) set x=y where a=b

此方法的最大问题是您增加了表的“更新”次数。尝试使用一个进程消耗(更新+删除)和其他人在表中插入数据,你会发现大约有一百万条记录,它开始崩溃。

我宁愿为数据库拥有一个消费者,并使用消息队列将处理数据传递给其他消费者。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top