何为嵌套事务
简单解释:在一个会话中开启了多个事务
(@@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 将该事务提交掉)