SQL在删除子表行时锁定父表

The*_*per 7 t-sql sql-server

TLDR:尝试在包含另一个"父"表的外键的"子"表上按主键删除行时,它会在子事务的持续时间内锁定父表.使用外键/子删除可以做些什么来防止锁定发生?

示例场景


建立:

IF ( SELECT OBJECT_ID('dbo.Child')
   ) IS NOT NULL
   DROP TABLE dbo.Child;
IF ( SELECT OBJECT_ID('dbo.Parent')
   ) IS NOT NULL
   DROP TABLE dbo.Parent;
GO
CREATE TABLE dbo.Parent
       (
         ID INT PRIMARY KEY
                IDENTITY(1, 1) ,
         Value TINYINT NOT NULL
       );
CREATE TABLE dbo.Child
       (
         ID INT PRIMARY KEY
                IDENTITY(1, 1) ,
         Parent_ID INT CONSTRAINT FK_Child_Parent_ID FOREIGN KEY REFERENCES Parent ( ID ) ,
         Value TINYINT NOT NULL
       );
GO
INSERT  INTO dbo.Parent
        ( Value )
VALUES  ( 1 ),
        ( 2 );
INSERT  INTO dbo.Child
        ( Parent_ID, Value )
VALUES  ( 1, 1 );
GO
Run Code Online (Sandbox Code Playgroud)

连接1 :(先运行)

BEGIN TRANSACTION;
DELETE  dbo.Child
WHERE   Child.ID = 1;
Run Code Online (Sandbox Code Playgroud)

连接2:

DELETE  dbo.Parent
WHERE   Parent.ID = 2;
Run Code Online (Sandbox Code Playgroud)

在上面的场景中,连接2的删除将被连接1阻止,直到该连接完成打开的事务 - 即使在父项上删除的行与被删除的子项引用的行不同(事实上)没有任何子条目).

有没有办法修改约束以允许此方案工作?

Ale*_*nko 6

在这种情况下,您只需要在列Parent_ID上创建索引.它将强制查询优化器使用Index Seek操作

CREATE INDEX x ON dbo.Child(Parent_ID)

在此输入图像描述

否则,Connection2将在表Child上进行Clustered Index Scan,它由Connection1阻塞

在此输入图像描述