SQL Server行锁

时间:2018-07-11 13:00:01

标签: sql sql-server database

使用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需要等待。

1 个答案:

答案 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都会执行其语句

了解更多信息:https://littlekendra.com/2016/02/04/why-rowlock-hints-can-make-queries-slower-and-blocking-worse-in-sql-server/