数据库队列的并行处理

本文关键字:并行处理 队列 数据库 | 更新日期: 2023-09-27 17:47:46

有一个小系统,在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

处理后,它将表的处理列设置为其他内容,如"done"或其他内容。

关于这种方法,我有三个问题。

第一:这个表格可以用吗?

第二:如果它有效,它有效吗?你对创建这样一个发行版还有其他想法吗?

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

数据库队列的并行处理

这是可行的,但您可能会发现,在多个进程尝试读取/更新相同数据时,会遇到阻塞或死锁。我为我们的一个系统编写了一个过程来做到这一点,该系统使用了一些有趣的锁定语义来确保这种类型的事情在没有阻塞或死锁的情况下运行,如本文所述。

这种方法对我来说是合理的,与我过去成功使用的方法类似。

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

除非你的应用程序的处理开销低到可以忽略不计,否则我会把"最高"值保持在较低的水平——也许只有1。当然,这完全取决于你的应用程序的细节。

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

关于您关于锁定的问题。您可以使用锁定提示来强制它只锁定行
update mytable with (rowlock) set x=y where a=b

这种方法最大的问题是增加了表的"更新"次数。只要一个进程消耗(更新+删除),其他进程在表中插入数据,你就会发现,在大约一百万条记录中,它开始崩溃。

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