一直在阅读很多僵局,当我认为我很清楚这里就出现了问题。
有两个类似的交易同时进行。它们如下所示:
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可以解决这个问题,但我错了。
答案 0 :(得分:3)
使用表/聚簇索引扫描的一个或两个更新很可能用于查找要更新的行 - 它通常会导致死锁。检查执行计划。