Sql server 当它';有必要检查@@trancount>;0在try catch块中?

Sql server 当它';有必要检查@@trancount>;0在try catch块中?,sql-server,sql-server-2008,tsql,transactions,try-catch,Sql Server,Sql Server 2008,Tsql,Transactions,Try Catch,有时我会看到下面的代码片段。如果@tracount>0需要begin try,什么时候需要if?他们两个?或者总是检查它是一种安全的方法(最佳实践),以防它在检查前回滚 begin tran begin try ... just several lines of sql ... if @@trancount > 0 commit tran end try begin catch if @@trancount > 0 rollback tran end catch 在处理

有时我会看到下面的代码片段。如果@tracount>0需要
begin try
,什么时候需要
if
?他们两个?或者总是检查它是一种安全的方法(最佳实践),以防它在检查前回滚

begin tran
begin try
  ... just several lines of sql ...
  if @@trancount > 0 commit tran
end try
begin catch
  if @@trancount > 0 rollback tran
end catch

在处理<代码> @ @ TrcUn>代码>:

时,我可以考虑一些场景。
  • 当前事务是从另一个存储过程调用的,该存储过程 它自己的交易
  • 当前事务由某个.NET代码使用其自己的 交易
  • 当前事务是唯一的事务

  • 我相信Remus Rusanu能够处理所有这些可能性。

    当您不使用@trancount时,嵌套事务存储过程的错误消息不会返回错误的确切原因,只是重新报告“回滚事务请求没有相应的begin事务”,否则它会给出错误的确切原因,因此,使用正确的语法很容易处理错误。

    检查的原因是,如果您在@trancount=0时提交trans或回滚它,则会出现以下错误消息异常:
    提交事务请求没有相应的开始事务。

    回答问题——如果@中间的代码可能已经执行了您启动的事务的提交或回滚,那么执行@ @转数的时间。因此,如果您正在调用存储过程(例如),那么在最后执行检查

    顺便说一句,与执行if@@tracount>0相比,我建议最好在代码块的开头检查@tracount,然后查看计数是否在最后增加,在这种情况下,根据try/catch执行提交或回滚

    特别是当您处于触发器中时,因为@@trancount始终为1,因此仅执行@@trancount>0可能会导致错误

    但是,即使您的代码只是在一个存储过程中,假设它是由另一个本身具有打开事务的过程调用的,如果您的代码出错并回滚,那么外部存储过程也将回滚其事务(请参阅)

    所以

    开始训练 打印@@TRANCOUNT

    开始训练 打印@@TRANCOUNT

    回滚传输 打印@@TRANCOUNT

    显示 1. 2. 0


    基本上,如果中间的代码正在调用其他过程,则需要执行IF @ @ TrCube检查。

    示例似乎试图避免嵌套事务。有必要吗?对我来说,这个想法是,如果这个新操作是嵌套事务,那么保存它。如果出现错误,并且这是一个嵌套事务,则只回滚嵌套事务,以免影响原始调用方。4:当您调用垃圾加密的API SP时,如果SP确定存在问题,它不会回滚自己的事务…那么?所以,检查一下@trancount与否?我认为这个被接受的“答案”绝对不能回答这个问题。