BEGIN TRY
                BEGIN TRANSACTION T
 --sql1
 --sql2 
 --sql3
                COMMIT TRANSACTION T
            END TRY
            BEGIN CATCH
                IF @@TRANCOUNT > 0 
                    BEGIN                        ROLLBACK TRANSACTION T
                    END
            END CATCH
            
            
            --当sql2出错的时候,执行ROLLBACK TRANSACTION T,提示无法回滚 T。找不到该名称的事务或保存点。
--EXECUTE 后的事务计数指示缺少了 COMMIT 或 ROLLBACK TRANSACTION 语句。上一计数 = 0,当前计数 = 1。 --这样写有问题?

解决方案 »

  1.   

    COMMIT TRANSACTION T 这个已经提交了,下面rollback 就没用了
      

  2.   

    楼主的事务写的没有问题,是标准的写法,只是可能有些错误,会将事务置为uncommitable状态,你可以把sql2的具体内容发出来,我们一起研究一下。我的粗略的建议是:
    1.SET XACT_ABORT OFF
    2.可能是外面还有嵌套的事务,可以将ROLLBACK TRANSACTION T中的T去掉。
      

  3.   

    BEGIN TRY
      BEGIN TRANSACTION T
    --sql1
    --sql2 
    --sql3
      COMMIT TRANSACTION T
      END TRY
      BEGIN CATCH
      IF XACT_STATE()<>0 
      BEGIN  ROLLBACK TRANSACTION T
      END
      END CATCH
      

  4.   

    @@TRANCOUNT===============================
    每一个BEGIN TRAN 语句都会使@@TRANCOUNT增加1并且每一个COMMIT TRAN语句都会使其减少1。
    一个值为0的@@TRANCOUNT意味着没有打开的事务。
    在@@TRANCOUNT值从1降到0时结束的事务发生在外层事务提交的时候,每一个内部事务都需要提交。
    由于事务起始于第一个BEGIN TRAN并结束于最后一个COMMIT TRAN,因此最外层的事务决定了是否完全提交内部的事务。
    如果最外层的事务没有被提交,其中嵌套的事务也不会被提交。XACT_STATE()====================================================
    用于报告当前正在运行的请求的用户事务状态的标量函数。XACT_STATE 指示请求是否有活动的用户事务,以及是否能够提交该事务。
    返回值  含义1     当前请求有活动的用户事务。请求可以执行任何操作,包括写入数据和提交事务。0     当前请求没有活动的用户事务。-1   当前请求具有活动的用户事务,但出现了致使事务被归类为无法提交的事务的错误。请求无法提交事务或回滚到保存点;它只能请求完全回滚事务。请求在回滚事务之前无法执行任何写操作。请求在回滚事务之前只能执行读操作。事务回滚之后,请求便可执行读写操作并可开始新的事务。当批处理结束运行时,数据库引擎将自动回滚所有不可提交的活动事务。如果事务进入不可提交状态时未发送错误消息,则当批处理结束时,将向客户端应用程序发送一个错误消息。该消息指示检测到并回滚了一个不可提交的事务。有关无法提交的事务的详细信息,请参阅在 Transact-SQL 中使用 TRY...CATCH。
    XACT_STATE 和 @@TRANCOUNT 函数都可用于检测当前请求是否具有活动的用户事务。@@TRANCOUNT 不能用于确定事务是否已分类为不可提交的事务。XACT_STATE 不能用于确定是否有嵌套事务。