SqlServer 2005:没有共享记录的死锁问题

Ste*_*ger 5 deadlock sql-server-2005

我有两个不访问任何常见记录的事务的死锁问题.也没有锁升级.所以我无法解释为什么死锁是可能的.

当两个此类事务同时执行时发生死锁:

begin transaction

update A set [value] = [value]
where id = 1; /* resp. 2 */

/* synchronize transactions here */

SELECT * 
FROM  
 A inner join B on A.B_FK = B.id
 inner join C on C.A_FK = A.id
WHERE 
 A.[value] = 1; /* resp. 2 */

rollback;
Run Code Online (Sandbox Code Playgroud)

这些是用于设置场景的表和数据:

CREATE TABLE A (
  id INT NOT NULL,
  [value] INT,
  B_FK INT
  primary key (id)
)

CREATE TABLE B (
  id INT NOT NULL,
  primary key (id)
)

CREATE TABLE C (
  id INT NOT NULL,
  A_FK INT
  primary key (id)
)

INSERT INTO A VALUES(1, 1, 1) 
INSERT INTO B VALUES(1) 
INSERT INTO C VALUES(1, 1) 

INSERT INTO A VALUES(2, 2, 2) 
INSERT INTO B VALUES(2) 
INSERT INTO C VALUES(2, 2) 
Run Code Online (Sandbox Code Playgroud)

A位于三个表的中间.如果我在查询中更改了任何内容,例如删除其中一个连接的表,B或者C没有死锁.当我过滤A.id而不是相同时A.value.

死锁图告诉我他们都希望将S锁设置为表的主键索引A.再说一遍:没有锁升级.

我正在使用SqlServer 2005.

  • 如果不访问任何常见数据,为什么这些交易会发生冲突 有谁能解释一下?
  • 我该怎么做才能避免它?我正在使用NHibernate,无法轻松更改查询.
  • 可能是SqlServer问题?

非常感谢.

Wol*_*ang 7

可能会发生冲突,因为SQL-Server不仅会锁定行级别,还会锁定页面甚至表级别.

这意味着即使记录本身并未实际使用,也可以锁定记录,但只能记录"附近"的记录.

SQL Server Lock Contention Tamed可能会有所帮助