外键会导致死锁并阻碍 READ COMMITTED SNAPSHOT 吗?

Tim*_*ter 20 sql-server-2005 sql-server deadlock

这是一个后续问题:https : //stackoverflow.com/questions/7684477/is-it-possible-to-set-transaction-isolation-level-snapshot-automatically

尽管READ_COMMITTED_SNAPSHOT ON.

所以我有两个问题:

  1. 我如何检查事务隔离级别快照是否按预期工作/完全正常工作?
  2. 我假设外键(在 Web 应用程序的表中到报告表)负责死锁。我发现了这篇有趣的文章

注意SQL Server 在验证外键时获取共享锁,即使事务使用的是已提交读快照(使用行版本控制已提交读)或快照隔离级别。在使用这些事务隔离级别时检查事务的死锁图时请注意这一点。如果您看到共享锁,请检查是否在外键引用的对象上获取了这些锁。

我如何检查 FK 是否真的对死锁/超时情况负责,这是否意味着我可以删除这些外键以防止死锁(什么是可以接受的努力)?

注意:我只是从导致死锁的表中读取数据。

非常感谢有关此主题的任何想法。


编辑 这里是一个死锁图。也许有人可以帮助我了解导致僵局的原因。当两个事务想要写入同一个表(一个更新和一个插入,插入作为存储过程)时,似乎没有任何报告运行仅由 Web 应用程序引起。为什么它需要页锁以及如何只启用行锁?Insert-SP 已经使用TRANSACTION ISOLATION LEVEL REPEATABLE READ.

我强烈怀疑两个触发器(一个更新和一个插入)是造成死锁的原因。这是插入触发器:

CREATE TRIGGER [dbo].[CreateRMAFiDates] 
   ON  [dbo].[RMA] 
   AFTER INSERT
AS 
BEGIN
    SET NOCOUNT ON;

    UPDATE RMA 
    SET [fiCreationDate]=(SELECT idDate FROM tdefDate 
        WHERE CONVERT(VARCHAR, INSERTED.Creation_Date, 112) = tdefDate.Text),
        [fiPopDate]=(SELECT idDate FROM tdefDate 
        WHERE CONVERT(VARCHAR, INSERTED.POP_Date, 112) = tdefDate.Text),
        [fiManufactureDate]=(SELECT idDate FROM tdefDate 
        WHERE CONVERT(VARCHAR, INSERTED.Manufacture_Date, 112) = tdefDate.Text)
    FROM INSERTED;
END
Run Code Online (Sandbox Code Playgroud)

所以这个触发器更新了 RMA-Table 导致更新触发器触发的原因(类似的)。死锁图是否证实了我的假设?我想我会删除这些触发器并创建一个每天运行一次的 SP,这已经足够了,因为这些列仅适用于 SSAS-Cube(Molap)。

编辑:顺便说一下,因为我删除了这些触发器,所以不再有死锁:)

Rem*_*anu 16

如果 SQLCAT 团队说 FK验证是使用读提交隔离完成的,那么他们必须知道他们在说什么。强调验证。真正的问题是为什么报告会触发 FK 验证?验证发生在写入,而报告应该是读取。要么您的报告导致写入,在这种情况下快照隔离级别将无济于事,要么死锁的原因不同。

取得进展的唯一方法是捕获死锁图。

至于另一个问题,如何检查是否在快照隔离下操作:查看sys.dm_tran_active_snapshot_database_transactions.