【问题标题】:How do I create a stored procedure whose effects cannot be rolled back?如何创建其效果无法回滚的存储过程?
【发布时间】:2011-09-12 16:53:19
【问题描述】:

我想要一个存储过程,将记录插入 tableA 并更新 tableB 中的记录。

存储过程将从触发器中调用。

即使触发器的最外层事务回滚,我也希望tableA中插入的记录存在。

tableA 中的记录是线性连接的,我必须能够重建线性连接。

只有通过触发器才能对 tableA 进行写访问。

我该怎么做?

【问题讨论】:

  • 你看过 MSDN 中的嵌套事务吗?
  • @BalamBalam - 嵌套事务不像您在 SQL Server 中所期望的那样工作。提交内部事务并回滚外部事务,内部事务也会回滚。
  • 我在写自己更长的问题时偶然发现了这一点,Aaron Bertrand 的回答同样适用于这个问题,所以这里有更多的关键字,以防它对谷歌有所帮助:T-SQL 中的并行事务/ 允许交易中的副作用

标签: sql-server tsql stored-procedures transactions


【解决方案1】:

您正在寻找的是自治事务,而今天的 SQL Server 中不存在这些事务。请对以下项目进行投票/评论:

http://connect.microsoft.com/SQLServer/feedback/details/296870/add-support-for-autonomous-transactions

http://connect.microsoft.com/SQLServer/feedback/details/324569/add-support-for-true-nested-transactions

您可以考虑使用 xp_cmdshell 或 CLR 到 SQL 引擎之外返回(SQL Server 无法回滚这些操作)...但是这些方法并非没有自身的问题。

另一个想法是使用INSTEAD OF triggers - 您可以记录/更新其他表,然后决定不继续执行实际操作。

编辑

根据@VoodooChild 的建议,您可以使用@table 变量来临时保存您可以在回滚后引用的数据——这些数据将在回滚后继续存在,这与插入#temp table 不同。

【讨论】:

    【解决方案2】:

    请参阅此帖子Logging messages during a transaction 以了解实现您想要的(有些复杂的)有效方法:即使事务已回滚,对日志记录表的插入也会保持不变。 Simon 提出的方法有几个优点:不需要对调用者进行更改,速度快且可扩展,并且可以在触发器内安全地使用。 Simon 的示例用于记录,但插入可以用于任何内容。

    【讨论】:

      【解决方案3】:

      一种方法是创建一个指向本地服务器的链接服务器。在链接服务器上执行的存储过程不会回滚:

      EXEC LinkedServer.DbName.dbo.sp_LogInfo 'this won''t be rolled back'
      

      您可以从触发器调用远程存储过程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-10
        • 1970-01-01
        • 1970-01-01
        • 2020-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多