2008-10-30 94 views
4

有一个小型系统,其中一个数据库表作为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)?

回答

6

这是可行的,但你可能会发现你会遇到阻塞或死锁,其中多个进程尝试读取/更新相同的数据。我编写了一个程序来为我们的一个系统完成这个操作,它使用了一些有趣的锁定语义来确保这种类型的事物在没有阻塞或死锁的情况下运行,described here

+0

这是非常好的,正是我所需要的。谢谢。 – Biri 2008-10-30 09:12:03

+0

不错。我说我会感兴趣;-) – philsquared 2008-10-30 09:35:29

1

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

此外,行/表只会在更新和选择操作发生时被锁定,所以我怀疑行vs表问题确实是一个主要考虑因素。

除非您的应用程序的处理开销太低以至于微不足道,否则我会保持“最高”值较低 - 可能只有1个。当然,这完全取决于您的应用程序的细节。

说了这么多,我不是一个DBA,因此也将拥有更多的专家解答

1

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

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

此方法的最大问题是您增加了对该表的“更新”数量。试试这只需要一个进程(更新+删除)和其他人在表中插入数据,你会发现在大约一百万条记录中,它开始崩溃。

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