在单个表上更新两个不同的行时死锁

时间:2012-01-17 19:23:07

标签: sql-server sql-server-2008-r2

一直在阅读很多僵局,当我认为我很清楚这里就出现了问题。

有两个类似的交易同时进行。它们如下所示:

BEGIN TRAN //read_committed_snapshot ON

//an application sends insert query
INSERT INTO t1 VALUES('Name',15)

//later on application sends update query for the newly inserted row
UPDATE t1 SET name='NewName', number=16 WHERE id = 10 //this ID is the id of the inserted row. 

COMMIT

给定的代码不是我在我的应用中使用的确切代码,但想法是一样的,它只有更多列。

表t1具有主键ID,一些非聚簇索引。

同时运行其中两个事务后,它会死锁。分析器说,对于每个冲突的进程,死锁的查询都是UPDATE t1 SET name='NewName', number=16 WHERE id = :id

抱歉,我没有死锁的XML,但是分析器告诉两个进程都有X锁,并且他们都尝试获取U锁。

process 1
owner - X
waiter - U

process 2
owner - X
waiter - U

t1表显示为对象,PK_id索引为indexname

那么这里究竟发生了什么?每个事务更新同一个表中的不同行,为什么会死锁?

网上的很多例子都说'嘿,因为它扫描索引的方式,它扫描一个事务的pk索引和另一个事务的其他非聚集索引'但是它们的探查器死锁图在indexname下显示不同的值,所以这与我的不一样,索引名称是相同的。

任何想法如何解决这个问题?这让我疯狂。我认为启用read_committed_snapshot可以解决这个问题,但我错了。

1 个答案:

答案 0 :(得分:3)

使用表/聚簇索引扫描的一个或两个更新很可能用于查找要更新的行 - 它通常会导致死锁。检查执行计划。