嵌套事务回滚

SqlServer里,嵌套事务的层次是由@@TranCount全局变量反映出来的。


每一次Begin Transaction都会引起@@TranCount1。而每一次Commit Transaction都会使@@TranCount1,而RollBack Transaction会回滚所有的嵌套事务包括已经提交的事务和未提交的事务,而使@@TranCount0。会导致外层事务RollBack Transaction失败。

对于嵌套事务, ROLLBACK TRAN +事务名称回滚 , 这样 @@TranCount就不会减少,回滚后Commit,使@@TranCount正常-1.

 BEGIN TRAN --@@TRANCOUNT值为0 
      SELECT @@TRANCOUNT --值为1 
          BEGIN TRAN 
                SELECT @@TRANCOUNT --值为2 
          COMMIT TRAN 
          SELECT @@TRANCOUNT --值为1 
  ROLLBACK TRAN 
  SELECT @@TRANCOUNT --值为0     

 --又如

  BEGIN TRAN --@@TRANCOUNT值为0 
      SELECT @@TRANCOUNT --值为1


      SAVE TRAN t1 
      SELECT @@TRANCOUNT --值为1 
          BEGIN TRAN 
                SELECT @@TRANCOUNT --值为2 
          ROLLBACK TRAN t1 
          SELECT @@TRANCOUNT --注意这里的值为2
          Commit
          SELECT @@TRANCOUNT --值为1
  IF @@TRANCOUNT>0 
  ROLLBACK TRAN 
  SELECT '处理结束', @@TRANCOUNT --为0

 

嵌套事务比较理想的写法:

  DECLARE @TranCounter INT;
   SET @TranCounter = @@TRANCOUNT;

   IF @TranCounter > 0 --表示为嵌套事务
       SAVE TRANSACTION ProcedureSave;

   ELSE    --表示非嵌套事务
       BEGIN TRANSACTION;

   BEGIN TRY
     ........
     IF @TranCounter = 0      --只有外部事务需要提交,内部只是一部分,不需要提交事务    
     COMMIT TRANSACTION;
   END TRY 
   BEGIN CATCH
     IF ( @TranCounter = 0 )  
      BEGIN
         ROLLBACK TRANSACTION;
      END
      ELSE
         ROLLBACK TRANSACTION ProcedureSave;
   END CATCH;


 

你可能感兴趣的:(事务,锁)