【问题标题】:Does EXEC Commit a Transaction in TRY/CATCH block?EXEC 是否在 TRY/CATCH 块中提交事务?
【发布时间】:2021-12-25 03:26:43
【问题描述】:

我有一个包含事务的 TRY/CATCH 块,我想根据执行存储过程的结果回滚。

BEGIN TRY
     BEGIN TRAN
          INSERT Record
          --Business validation
          EXEC StoredProcedure  --This should throw error
          PRINT 'Commit Tran'
          COMMIT TRAN
END TRY
BEGIN CATCH
     PRINT 'In CATCH Block'
     ROLLBACK TRAN;
 END CATCH
 PRINT 'After END CATCH'

在我的测试中,插入记录已提交,存储过程按预期失败,未打印 PRINT 'COMMIT Tran',代码被发送到 CATCH 块并出现以下错误:"The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION."

如果我将 EXEC StoredProcedure 替换为设计为失败的 INSERT,则原始 INSERT 不会提交,并且 CATCH 块中的 ROLLBACK 可以正常运行而没有错误。

所以问题是 EXEC StoredProcedure 如何影响事务,我该如何解决这个问题?

【问题讨论】:

  • 在您流程的每个步骤中,@@TRANCOUNT 的值是多少?尝试添加 PRINT 语句来捕获这些 - 它可能有助于说明正在发生的事情
  • 您说“INSERT 记录已提交”-您能否在代码中显示您确定的位置?另外,您的存储过程如何出错:是THROW 还是RAISERROR,该过程中是否有事务控制语句?
  • @paneerakbari 1) @@TRANCOUNTsays 在 INSERT 记录之后有 1 个事务,在 CATCH 块中有 0 个事务。 2)我说“插入记录已提交”,因为在过程失败后记录仍保留在表中。 3) RAISERROR 的存储过程错误,并且该过程中没有事务控制

标签: sql-server tsql


【解决方案1】:

您的StoredProcedure 正在结束交易,无论是明确的还是隐含的。也许它正在调用其他确实有提交的过程,或者它正在某处进行直接的“提交”

这是一个使用您的示例的演示,它不会隐式/显式地https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=1d02ee0255aa6c7131dd7e300704bab5

【讨论】:

  • 这就是原因。嵌套存储过程有一个深埋的提交。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 2013-07-08
  • 2011-04-09
相关资源
最近更新 更多