批处理事务 - 为什么会进入无限循环?

时间:2012-05-10 15:19:38

标签: sql sql-server-2008 transactions

所以,我遇到了一些代码,它可以帮助我批量更新一个大表(100m +记录),如下所示:

--Declare variable for row count
set rowcount 50000
go

Declare @rc int
Set @rc=50000

While @rc=50000
 Begin

  Begin Transaction

  --Use tablockx and holdlock to obtain and hold 
  --an immediate exclusive table lock. This unusually
  --speeds the update because only one lock is needed.

    update  MyTable With (tablockx, holdlock)
    set TestField='ABC'

    ----Get number of rows updated
    ----Process will continue until less than 50000
    select @rc=@@rowcount


  Commit
 End

问题是,这会进入一个无限循环,引发(50000行受影响)直到天结束。顺便提一下,如果表的记录少于50000,则上述代码正确退出。任何人都知道如何解决这个问题?

由于

1 个答案:

答案 0 :(得分:3)

如果MyTable中有50000或更多记录,则它将始终更新。您的更新中没有where子句会缩小字段范围,最终使您更新<50000条记录。

据推测,您打算只更新TestField&lt;&gt;的记录。 'ABC'所以你没有再次执行相同的更新。

当您考虑使用where子句时,请考虑使用聚簇索引,以便可以对更新执行索引查找/部分扫描,而不是全表扫描。

顺便说一句,不需要HOLDLOCK提示,因为它在事务提交后立即释放,也不需要显式事务,因为更新本身是事务。由于它可以避免锁定升级,因此可以产生轻微的改进。