在我们的实时/生产数据库中,我正在尝试向表中添加触发器,但一直未成功。我已经尝试了几次,但创建触发器语句需要30多分钟才能完成,我已经取消了它。

该表通常由几个不同的进程读取/写入。我已经禁用了更新表的计划作业,并且在表上的活动较少时尝试了,但是我无法阻止访问表的所有内容。

我不认为create trigger语句本身存在问题。 create trigger语句在测试环境中成功且快速,并且在将行插入/更新到表时,触发器可正常工作。虽然当我在测试数据库上创建触发器时,表上没有负载,但它的行数要少得多,这与实时/生产数据库上的不同(100对13,000,000 +)。

这是我正在尝试运行的创建触发器语句

CREATE TRIGGER [OnItem_Updated] 
    ON  [Item]
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF update(State)
    BEGIN
        /* do some stuff including for each row updated call a stored 
          procedure that increments a value in table based on the 
          UserId of the updated row */
    END
END

在更新行或是否有多行时,是否存在在表上创建触发器的问题?

在SQLServer中,默认情况下会启用触发器。是否可以默认创建禁用的触发器?

还有其他想法吗?

有帮助吗?

解决方案

问题可能不在表本身中,而是在必须更新以创建触发器的系统表中。如果您正在进行任何其他类型的DDL作为正常流程的一部分,他们可能会坚持下去。

使用sp_who找出该块的来源,然后从那里进行调查。

其他提示

我相信CREATE Trigger会尝试锁定整个表。

如果你在该桌面上有很多活动,可能需要等待很长时间,你可能会造成死锁。

对于任何架构更改,您应该真正获得数据库的每个人。

那说它很容易放入“小”的东西。活动连接更改。您应该查看锁定/连接以查看锁争用的位置。

这很奇怪。 AFTER UPDATE 触发器不需要检查表中的现有行。我想你可能无法在桌面上获得锁定以添加触发器。

你可能会尝试创建一个基本上什么都不做的触发器。如果你不能创建它,那么这是一个锁定问题。如果可以,那么您可以禁用该触发器,将您想要的代码添加到正文中,然后启用它。 (我不相信你可以在创建过程中禁用触发器。)

部分问题也可能是触发器本身。您的触发器是否会意外更新表的所有行?测试数据库中的100行与13,000,000之间存在很大差异。当您拥有如此庞大的数据集而无法预测性能时,针对如此小的集合开发代码是一个非常糟糕的主意。适用于100条记录的SQL可以完全锁定数百万小时的系统。你真的想知道在开发中,而不是当你提升为prod时。

在触发器中调用存储过程通常是一个非常糟糕的选择。这也意味着你必须遍历记录,这是触发器中更糟糕的选择。触发器必须alawys帐户进行多个记录插入/更新或删除。如果有人插入100,000行(如果你有13,000,000条记录,则不太可能),然后循环通过基于记录的存储过程可能需要数小时,锁定整个表并导致所有用户想要追捕开发人员并杀死(或者至少是maim)因为他们无法完成他们的工作。

我甚至不考虑将这个触发器放在prod上,直到你测试一个大小相同的记录集来刺激。

我的朋友丹尼斯写了这篇文章,说明了为什么在你有大量信息的情况下测试一小部分信息会给你在开发方面没有注意到的prd造成困难: http://blogs.lessthandot.com/index.php/DataMgmt/?blog=3&title=your-testbed-has-to-have-the-same-volume& DISP =单及更多= 1和C = 1&安培; TB = 1&安培; PB = 1#C1210

在更改触发器之前运行 DISABLE TRIGGER triggername ON tablename ,然后使用 ENABLE TRIGGER triggername ON tablename重新启用它

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top