Sql server Update语句中的死锁和UPDLOCK提示的使用
对于下面的事务,当为同一订单同时调用此事务时,我偶尔会收到死锁错误Sql server Update语句中的死锁和UPDLOCK提示的使用,sql-server,transactions,deadlock,Sql Server,Transactions,Deadlock,对于下面的事务,当为同一订单同时调用此事务时,我偶尔会收到死锁错误 BEGIN TRANSACTION IF EXISTS (SELECT orderID FROM [Orders]WHERE orderID=@OrderId) BEGIN UPDATE [Orders] SET [orderXml] =@orderXml ,[updatedDateTime] = @updatedDateTime WHERE [
BEGIN TRANSACTION
IF EXISTS (SELECT orderID FROM [Orders]WHERE orderID=@OrderId)
BEGIN
UPDATE [Orders] SET
[orderXml] =@orderXml
,[updatedDateTime] = @updatedDateTime
WHERE
[orderId] = @OrderId AND @updatedDateTime > updatedDateTime
END
if @@ROWCOUNT = 0
BEGIN
DELETE OrderLine
WHERE
orderID=@OrderId
END
COMMIT TRANSACTION
死锁图:
<resource-list>
<keylock hobtid="72057594039042048" dbid="13" objectname="OrderDB.dbo.Orders" indexname="PK_Order" id="lockac2e8d80" mode="U" associatedObjectId="72057594039042048">
<owner-list>
<owner id="process80736748" mode="U"/>
</owner-list>
<waiter-list>
<waiter id="process80739b88" mode="U" requestType="convert"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594039042048" dbid="13" objectname=" OrderDB.dbo.Orders" indexname="PK_Order" id="lockac2e8d80" mode="U" associatedObjectId="72057594039042048">
<owner-list>
<owner id="process80739b88" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="process80736748" mode="X" requestType="convert"/>
</waiter-list>
</keylock>
</resource-list>
PK_Order是Orders表的OrderId(varchar)列上的主键。该表在UpdateDateTime(datetime2)列上还有一个非聚集索引
问题:当我在上面的update语句中使用WITH(UPDLOCK)提示时,死锁似乎消失了。
建议使用UPDLOCK提示还是将事务隔离级别设置为Serializable。
此外,建议在上述delete语句中也使用UPDLOCK提示。这是死锁的典型情况。访问模式是先读后写的。两个都是trans-read,然后都无法写入 使用“写”锁(
UPDLOCK
)的解决方案很好。使用<代码> UPDROCK、ROLKOLD、HOLDROCK < /代码>,我认为这是对这种情况最好的实践。
SERIALIZABLE
没有帮助,因为模式仍然是先读后写的
DELETE
不需要额外的锁定,因为事务已经获得了对相关行的独占访问权