代码之家  ›  专栏  ›  技术社区  ›  Biri

数据库队列的并行处理

  •  4
  • Biri  · 技术社区  · 16 年前

    有一个小型的系统,其中有一个数据库表作为MSSQL2005上的队列。有几个应用程序正在写入此表,其中一个应用程序正在以FIFO方式读取和处理。

    我必须让它更高级一点,才能创建一个分布式系统,在那里可以运行多个处理应用程序。结果应该是2-10处理应用程序应该能够运行,并且在工作期间不应该相互干扰。

    我的想法是扩展队列表,其中一行显示一个进程已经在处理它。处理应用程序将首先使用其Identifyer更新表,然后请求更新的记录。

    所以像这样:

    start transaction
    update top(10) queue set processing = 'myid' where processing is null
    select * from processing where processing = 'myid'
    end transaction
    

    处理之后,它将表的处理列设置为其他内容,如“完成”或其他内容。

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

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

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

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

    4 回复  |  直到 14 年前
        1
  •  6
  •   Jeff Davis    14 年前

    这是可行的,但您可能会发现在多个进程尝试读取/更新同一数据时会遇到阻塞或死锁。我为我们的一个系统编写了一个过程,它使用一些有趣的锁语义来确保这类事情在没有阻塞或死锁的情况下运行, described here .

        2
  •  1
  •   philsquared    16 年前

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

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

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

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

        3
  •  1
  •   mjallday    16 年前

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

    update mytable with (rowlock) set x=y where a=b
    
        4
  •  1
  •   jeet    16 年前

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

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