Sqlserver——异常总结——关于嵌套事务

何为嵌套事务

简单解释:在一个会话中开启了多个事务

(@@TranCount-------全局参数,用于查看当前会话事务层数,下文会提到)

例如:

                        BEGIN TRAN; 
								----查询事务层数
                        SELECT  @@TRANCOUNT AS N'事务层数';

                        INSERT  INTO tt( Id, Name, CreateDate )	----插入1
                        VALUES  ( 1, 'test', GETDATE() );

                        BEGIN TRAN;

                        INSERT  INTO tt( Id, Name, CreateDate )	----插入2
                        VALUES  ( 2, 'test', GETDATE() );
								----查询事务层数
                        SELECT  @@TRANCOUNT AS N'事务层数';

                       

可以通过@@TranCount 查到当前会话的事务嵌套层数

一般的使用场景-->多个存储过程嵌套的时候会出现事务嵌套的情况

要点、特性:

1、在嵌套事务中使用Commit Tran 会按照事务嵌套的层数,依次提交最内存的事务,每提交一次@@TranCount的值-1

(例如上面那个例子,有2层事务,需要2次 Commit Tran 提交才能将数据完全提交给数据库写入

   并且是依次按照内层事务的顺序依次提交,即先提交  '插入2' ,再提交 '插入1')

2、在嵌套事务中使用了回滚操作RollBack Tran ,会导致整个事务完全回滚(不论层数,全部回滚) ,@@TranCount的值重置为0

     所以在存储过程嵌套的时候,如果子存储过程报错,导致事务回滚,会将父存储过程的事务一并回滚,

    导致在父存储过程中执行rollback tran 或者 commit tran 语句的时候会报错误提示

3、可以通过保存事务节点的方式来进行回滚指定的事务节点,而非回滚全部事务


-----保存事务节点1
BEGIN TRAN 
SAVE TRAN t1

		----查询事务层数
		SELECT @@TRANCOUNT AS N'事务层数'
	
		INSERT INTO dbo.tt
		SELECT 246,NEWID(),GETDATE()


-----保存事务节点2
		BEGIN  TRAN 
		SAVE TRAN t2

		----查询事务层数
		SELECT @@TRANCOUNT AS N'事务层数'

        INSERT INTO dbo.tt
		SELECT 135,NEWID(),GETDATE()

		----回滚指定事务节点
		ROLLBACK TRAN t2

		----回滚之后将t2事务提交掉
		COMMIT TRAN t2

COMMIT TRAN

		----查询表情况
		SELECT * FROM dbo.tt

     

     如图,最终的结果是 外层事务t1中的 246数据被写入数据库,而内层事务t2中的 135数据被回滚

   (PS:要注意的是当使用 回滚事务指定节点的时候,@@TranCount 是无法被重置为0/或者减少1的

       所以需要在回滚指定节点之后,作一次commit tran 将该事务提交掉)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值