Sql server 更新单个表上的两个不同行时发生死锁

Sql server 更新单个表上的两个不同行时发生死锁,sql-server,sql-server-2008-r2,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='

我读了很多关于死锁的书,当我认为我很清楚的时候,问题来了

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

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和一些非聚集索引

在同时运行其中两个事务后,它会死锁。探查器说,对于每个冲突进程,死锁查询是this
updatet1 SET name='NewName',number=16,其中id=:id

很抱歉,我没有死锁的XML,但是探查器告诉我两个进程都有X锁,并且都试图获取U锁

process 1
owner - X
waiter - U

process 2
owner - X
waiter - U
t1
表显示了作为对象的进程和作为
indexname
的PK_id索引

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

网络上的许多示例都说“嘿,这是因为它扫描索引的方式,它扫描一个事务的pk索引和另一个事务的一些其他非聚集索引”,但它们的探查器死锁图在
indexname
下显示了不同的值,因此这与我的情况不同,索引名称是相同的


有没有办法解决这个问题?这快把我逼疯了。我认为启用read_committed_snapshot可以解决这个问题,但我错了。

最有可能的情况是,您的一个或两个更新使用表/聚集索引扫描查找要更新的行-这通常会导致死锁。检查执行计划。

但它已经获得了独占锁,我可以理解这些锁是正在更新的行的密钥锁。尝试在两行之外的任何行上放置更新锁有什么意义。当我能够检查执行计划时(尽管我仍然很容易在那里迷路),表和页上会有意向锁,而且由于表有索引,查询也可能会干扰索引的更新