SQL Server 触发器插入导致锁定直到提交

Posted

技术标签:

【中文标题】SQL Server 触发器插入导致锁定直到提交【英文标题】:SQL Server trigger insert causes lock until commit 【发布时间】:2016-09-12 22:18:22 【问题描述】:

在通过触发器锁定相关表时遇到问题。

我正在插入表tCatalog(这有一个触发器可以简单地在另一个表tSearchQueue 中插入一条记录)。对tCatalog 的插入是在一个事务中,该事务具有许多其他功能,有时需要几秒钟。但是,tSearchQueue 表被锁定,直到可以提交事务。有没有办法避免这种情况?

INSERT INTO [dbo].[tSearchQueue] (Processed, SQL, sys_CreateDate) 
    SELECT      
        0, 'Test ' + cast(CatalogID as varchar(10)), getdate()
    FROM        
        inserted 


BEGIN TRAN t1
    DECLARE @catalogid int

    INSERT INTO tCatalog (ProgramID, sys_CreatedBy, ItemNumber, Description, UOMID) 
    VALUES (233, 1263, 'brian catalog4', 'brian catalog4', 416)

    SELECT @catalogid = SCOPE_IDENTITY()

    INSERT INTO tCustomAttributeCatalog (CatalogID, CustomAttributeID, DefaultValue, DefaultValueRead, sys_CreatedBy) 
    VALUES (@catalogid, 299, 'No', 'No', 1263)

    INSERT INTO tCustomAttributeCatalog (CatalogID, CustomAttributeID, DefaultValue, DefaultValueRead, sys_CreatedBy) 
    VALUES (@catalogid, 300, null, null, 1263)

COMMIT TRAN t1

【问题讨论】:

为什么tSearchQueue锁定了?是什么导致了这种行为??你能避免这种情况吗? @marc_s 这基本上就是我要问的问题。它似乎已被锁定,因为插入到 tCatalog 的事务尚未提交。我试图避免这种情况。 你能告诉我们插入TCatalog吗?但是,仅此一项不应该锁定另一个表TSearchQueue.... @marc_s 编辑问题以包含插入语句 谢谢 - 但再次:没有迹象表明对 TSearchQueue 表进行了任何操作.....不知道该表发生了什么,无法提供帮助,真的…… 【参考方案1】:

看起来您有一个后台进程希望收到更改通知,以便它可以进行某种重新索引。如果是这种情况,它被阻塞不一定是错误,因为如果事务没有提交,那么它也不应该对其进行索引。

所以顺序是:

开始交易 插入 tCatalog 触发插入 tSearchQueue 插入一些其他表格 执行长时间运行的操作 提交事务。

问题是另一个进程想要读取 tSearchQueue 但由于它被锁定而无法读取。

方案一:分批执行后台操作。

如果进程由于读取表格的机会太少而落后,那么一次读取多行可能会解决问题。 IE。每次它有机会读取队列时,它应该读取许多行,一次处理它们,然后将它们全部标记为一起完成(或视情况删除它们)。

选项 2:如果可能,首先执行长时间运行的操作:

开始交易 执行长时间运行的操作 插入 tCatalog 触发插入 tSearchQueue 插入一些其他表格 提交交易

其他进程现在发现 tSearchQueue 只锁定了很短的时间。 请注意,如果长时间运行的操作是文件副本,则可以使用CopyFileTransacted 将这些包含在事务中,或者如果操作失败,可以在“catch”语句中回滚副本。

选项3:后台进程避免锁定

如果其他进程主要尝试读取表,那么快照隔离可能会解决您的问题。这将只返回已提交的行,因为它们在时间点存在。结合行级锁定,这可能会解决您的问题。

或者,后台进程可能会使用NOLOCK 提示进行读取(脏读取)。这可能会导致从稍后回滚的事务中读取数据。但是,如果在单独的步骤中验证数据(例如,您只是为需要重新索引的对象编写标识符),这不一定是问题。如果索引过程可以处理不再存在或实际上没有更改的条目,那么虚假读取就无关紧要了。

【讨论】:

以上是关于SQL Server 触发器插入导致锁定直到提交的主要内容,如果未能解决你的问题,请参考以下文章

ibatis 插入 DB2 表会导致锁定阻止触发器工作

SQL Server锁定的DataReader行为

帮助 SQL Server 触发器在插入前截断错误数据

SQL Server 的锁定和阻塞

插入期间表被锁定...网站无法使用(sql server 2008)

SQL Server 触发器