【问题标题】:How exactly transactions work in Microsoft SQL Server事务在 Microsoft SQL Server 中究竟是如何工作的
【发布时间】:2021-04-16 22:57:44
【问题描述】:

我读过创建for insert trigger 会隐式创建事务。所以我可以从触发器中回滚事务并“撤消”插入。

是这样吗?

create trigger TRIGGER_NAME 
on TABLE_NAME
for insert
as
    declare @someVar = ....

    if @someVar > 0 
    begin
        rollback transaction
    end

那么在那种情况下,如果@someVar大于0,insert就会被取消,对吧?

create trigger TRIGGER_NAME 
on TABLE_NAME
for insert
as
    begin transaction
        declare @someVar = ....

        if @someVar > 0    
        begin
            rollback transaction
        end

        commit transaction

这样的话insert也会被取消吧?

当我们有两个for insert trigger 用于同一个表时会发生什么,并且他们都做rollback transaction 他们共享同一个隐式事务吗?

我在这件事上遇到了一些复杂情况,因此我尝试在每个触发器中创建自己的显式事务,但是对于 begin transaction,我无法正确使用 inserted,我无法提取任何值来自它。

【问题讨论】:

  • 不要在触发器中创建自己的事务!!!!永远不会......触发器在导致它触发的语句 (INSERT) 的上下文中运行(和事务)。是的 - 如果您检查某些条件并想中止,您可以执行ROLLBACK 并取消该交易。但永远不要在触发器中创建自己的“子事务”!
  • @marc_s 好的。有什么办法可以将交易嵌套在一起吗?当我在函数中调用函数时(例如将记录插入表的过程,它调用插入触发器。过程和触发器都使用事务。在触发器中回滚一直回滚到第一个事务,这不是我想要的)
  • 否 - SQL Server 具有用于嵌套事务的 语法 - 不幸的是,它缺少适当的功能。如果您在嵌套事务中回滚,则该回滚会影响所有事务,一直到最外层
  • @marc_s 所以不可能按照我想要的方式嵌套事务?我无能为力,对吧?
  • 这是正确的 - SQL Server 当前支持嵌套/独立事务。您的触发器始终在导致其触发的 SQL 语句的事务的上下文中执行 - 并且您只能在需要时回滚该事务(因此取消 all 插入 - 您无法区分行) - 不能比这更具体/详细....

标签: sql sql-server triggers transactions insertion


【解决方案1】:

事实上,事务就是会话的状态。没有其他的。所以你可以处于或不处于交易状态。当您执行 SQL 查询(不同于“命令”)时,有一个包含查询的隐式事务。当您在触发代码中时,事务状态处于活动状态,您可以回滚或提交。如果在触发代码中执行此命令(COMMIT 或 ROLLBACK)中的任何一个,您将引发 execption...但事务状态不再存在,直到您执行任何查询。

现在,如果您有多个触发器,则可以使用过程 sp_settriggerorder 管理触发器的串行执行优先级。

不建议为同一操作使用多个触发器,除非您必须按特定顺序执行它们。作为我在课程中给出的示例,我将同一动作的触发器数量限制为三个,具有这种特殊的优先级:

  1. 基于集合的约束的触发器
  2. 操作流程的触发器(客户端应用程序)
  3. 跟踪触发器

【讨论】:

  • 那么commit tran 呢?是否也将@@trancount 设置为0?
  • 我想出了类似的方法来管理引发错误。 pastebin.com/Dh9Aqw8A 它只是回退并在出现某些错误的情况下反转所有内容(ofc insert 只是为了测试而回滚)我想在我的大学项目中使用这种策略。这是个好主意吗?
  • COMMIT TRAN 降低深层次@@TRANCOUNT 直到这个层次归零,然后才真正的COMMIT。 ROLLBACK 取消事务并将深层@@TRANCOUT 设置为零。这在技术文献中被称为“嵌套事务管理的不对称模型”
猜你喜欢
  • 2015-04-23
  • 2013-07-06
  • 2023-04-01
  • 2011-06-26
  • 2021-08-15
  • 2012-06-08
  • 2011-10-11
  • 2013-07-05
相关资源
最近更新 更多