主要问题在于主题。
更详细地说:假设我们有一个表 T,它对表 U 有一个 FK 约束(为简单起见,对其 PK 有约束,并且两个表都在其 PK 上使用聚簇索引)。现在,我们在 T 中插入或更新一行,从而写入 FK 值。我的理解是
为 T 上插入/更改的行发出一个事务长度的 X 锁(以及上面的 IX 锁);
在 FK 值的 U 上发出一个事务长的 S 锁 - 这样其他任何事务都无法获取该键的 X 锁并更改它。
这是正确的吗?如果不是,FK 约束执行如何工作,以及它设置了哪些锁?
它可以解释我们的并行 ETL 系统上的死锁。
(我没有找到关于此问题的任何解释,也没有在公共场所找到,例如https://www.microsoftpressstore.com/articles/article.aspx?p=2233327&seqNum=3;此外,普遍的理解似乎是“SQL Server 读取并处理锁定的数据后立即释放共享锁”,这与我的事务长 S 锁有点矛盾……)。
编辑:这是死锁图的摘录:
Delete from ProduktGtin ....
...
INSERT INTO dbo.Produktzusatz ....
...
<pagelock fileid="1" pageid="33949422" ...
<owner id="processc45d4e8c8" mode="IX"/>
<waiter id="process780a4c8c8" mode="U" requestType="wait"/>
<pagelock fileid="1" pageid="6935000" ...
<owner id="process780a4c8c8" mode="IX"/>
<waiter id="processc45d4e8c8" mode="S" requestType="wait"/>