SQL从表中选择行并更新相同的行

时间:2011-11-01 22:59:33

标签: sql sql-server database sql-server-2005 sql-server-2008

我想:

  1. 从表中选择N行以进行处理,其中flag = 0
  2. 使用来自这N行
  3. 的值在第二个表上进行一些工作
  4. 更新这N行并设置flag = 1
  5. 我有并行进程一起完成同样的工作,我想确保所有人都能在独特的行上工作。我该如何确保?

2 个答案:

答案 0 :(得分:5)

我假设你在SQL Server上运行(因为标签),如果没有,那么我的答案不适用。 单独锁定是不够的。如果使用数据库记录锁定,SqL服务器将阻止尝试访问锁定行的其他进程,实际上您一次只能处理一行。 您的解决方案是将行锁定与READPAST提示相结合,以便跳过其他人锁定的行。以下是每个流程应该做的事情:

  1. 选择下一个未锁定的行进行处理并将其锁定
  2. 做好工作
  3. 更新行和结束交易
  4. select top 1 id, ... from TheTable with (updlock, readpast) where flag = 0

    //do the work now

    update TheTable set flag = 1 where id=<previously retrieved id>

    这里的好处是,选择下一个未锁定行并锁定它的操作是原子的,因此它保证没有其他人能够选择同一行。

答案 1 :(得分:0)

一种方法是让主程序将子句分发给子线程。

另一种方法是锁定表,获取CEIL(N/#processes)行,其中flag = 0,将标志更新为2,然后释放锁。然后下一个进程将继续,因为它获得了锁定,并且由于flag = 2,它将不会获得这些行。

你有两种方法来锁定表 - 你可以锁定整个事物,或者使用限制执行SELECT ... FOR UPDATE(不要获得太多行)。请参阅:SELECT FOR UPDATE with SQL Server

比将标志设置为2更好的是将标志设置为process_id。然后,您所要做的就是更新所有行以分配数字,然后让流程开始工作,每个行只检查自己的行。