【问题标题】:SQL Server database hangs on trigger executionSQL Server 数据库在触发器执行时挂起
【发布时间】:2023-04-06 18:48:01
【问题描述】:

我们在一个表上实现了 6-7 个触发器,其中有 4 个更新触发器。由于数据操作和条件,所有 4 个触发器都需要长时间处理。但是,每当触发器执行时,网站上的所有页面都会停止响应并为来自不同系统的每个其他用户挂起。即使我们在 SQL Server Management Studio 中对触发器保存表执行更新语句,它也会挂起。我们可以通过将这个触发代码转移到存储过程中并在表的更新语句之后调用这个存储过程来解决这个挂起的问题吗?

因为我认为触发器会在执行时阻止其他用户访问表。如果没有,那么任何人都可以提供解决方案。

【问题讨论】:

    标签: asp.net .net sql-server database sql-server-2008


    【解决方案1】:

    触发器很危险 - 每当事情发生时它们就会被触发,而您无法控制它们触发的时间和频率。

    您绝对应该在触发器中进行任何耗时的处理!触发器应该超级快,而且很瘦。

    如果您需要处理 - 让触发器将所需的信息记录到单独的“命令”表中,并让另一个进程(例如计划的 SQL 代理作业)检查该表中要执行的命令,然后执行这些命令- 独立于主应用程序,在单独的执行路径中。

    不要通过在触发器中进行过多的数据处理/操作来阻止您的主应用!这样做是错误的地方!

    【讨论】:

      【解决方案2】:

      我们能否通过将此触发器代码转移到存储过程中来解决这个挂起的问题 并在表的更新语句后调用这个存储过程?

      你有一个重达一吨的盒子。放在漂亮的包装里会变轻吗?

      触发器已编译。把它放到一个存储过程中,只不过是换装了而已。

      您的问题是您滥用触发器来进行繁重的处理——这是他们设计不应该做的事情。改变设计。

      因为我认为触发器在执行时会阻止其他用户对表的访问。

      好吧,触发器不会做这样的事情 - 所以你想错了。

      触发器执行它被告知要做的事情,而空触发器设置零锁(锁存在于任何触发它的位置)。如果您确实设置了一个桌子宽的锁 - 解雇这样做的人并重新设计。

      触发器应该快速、轻便且过快。没有繁重的处理。

      【讨论】:

        【解决方案3】:

        如果没有真正看到触发因素,就不可能自信地诊断出这种情况,但是这里......

        TRIGGER 不会这样设置锁,但如果它触发其他 UPDATE 语句,它们将需要锁,如果这些 UPDATE 语句触发其他触发器,那么您可能会产生连锁反应,产生您看起来的那种悲伤去体验。

        如果这听起来像可能发生的事情,那么删除触发器并通过在最后运行存储过程显式地进行处理可能会修复它。如果存储过程是垃圾,那么您仍然会遇到问题,但至少它们会更容易修复。尽量保证存储过程只更新需要更新的记录

        将功能转移到更新后运行的存储过程的主要问题是确保它实际上每次都运行。

        如果您的 asp.net 技能比您的 T-SQL 技能更强,那么这应该比解开 SQL 触发器网络更容易解决。

        另一个问题是更新完成和存储过程完成记录之间的中间状态将显示初始更改但不显示剩余更改。在您的情况下,这可能是问题,也可能不是问题

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-29
          • 1970-01-01
          • 2010-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-18
          • 1970-01-01
          相关资源
          最近更新 更多