使用SQL Server,我需要知道实际上是否可以对更新语句使用RowLock
。
我有以下问题:一个表不能同时接受同一记录中的更改,在不同的记录中没有问题。为此,我对所需记录使用SELECT
/ UPDLOCK
进行了NOWAIT
,如果没有错误返回,则允许更改。问题在于,如果用户A开始更改表记录1,则用户B开始编辑表记录2,则用户A仅在用户B也完成时才能完成其更新。它将保持锁定等待状态。
我读了很多关于它的话题,但那时都没有帮助。在我看来,Update
操作试图锁定整个表。它们是不同的行,应该有一些控制它的方法。
我有这种情况:
第1步:开始交易;
第2步:开始更新之前,我需要锁定记录: '使用(updlock,nowait)从Mytable中选择*,其中Id = MyId';
如果没有异常,则记录被锁定;
第3步:我的更新已完成: '更新MyTable设置some_field = some_value,其中Id = MyId';
第4步:提交交易;
问题是:
1-用户A,对记录1(Id = 1)开始更新;
2-用户B,对记录2(Id = 2)开始更新;
1-用户A需要执行更新。这是问题所在,直到用户B不提交或回滚您的事务之前,用户A需要等待。
答案 0 :(得分:0)
您需要做的是关闭聚集索引/非聚集索引中的ALLOW_PAGE_LOCKS
。如果您没有任何聚集/非聚集索引,则只需添加一个新索引即可!但是要注意行级锁定的副作用
ALTER INDEX YOURINDEX ON YOUR_TABLE SET ( ALLOW_PAGE_LOCKS = OFF )
重现问题
我有两个并发会话。会话1,尝试运行以下代码:
BEGIN TRAN
UPDATE dbo.tblTest SET Title='aa' WHERE id =1
WAITFOR DELAY '00:00:59'
ROLLBACK
会话2尝试运行以下代码:
UPDATE dbo.tblTest SET Title='bb' WHERE id =2
我先执行会话1,然后执行会话2,我们看到两个会话都卡在执行中...实际上,会话2将等待会话1释放锁!
为解决此问题,我使用以下代码更改了索引并关闭了ALLOW_PAGE_LOCKS
:
ALTER INDEX YOURINDEX ON YOUR_TABLE SET ( ALLOW_PAGE_LOCKS = OFF )
现在重试该场景...现在,虽然会话1处于执行阶段,但是无论会话1的记录上的锁定如何,会话2都会执行其语句