嵌套事务的问题

嵌套事务有几个特征, 帮助中这么说;

Microsoft® SQL Server™ 忽略提交内部事务。根据最外部事务结束时采取的操作,将提交或者回滚事务。如果提交外部事务,则内层嵌套的事务也会提交。如果回滚外部事务,则不论此前是否单独提交过内层事务,所有内层事务都将回滚。

对 COMMIT TRANSACTION 或 COMMIT WORK 的每个调用都应用于最后执行的 BEGIN TRANSACTION。如果嵌套 BEGIN TRANSACTION 语句,那么 COMMIT 语句只应用于最后一个嵌套的事务,也就是在最内层的事务。即使嵌套事务内部的 COMMIT TRANSACTION transaction_name 语句引用外部事务的事务名,该提交也只应用于最内层的事务。

ROLLBACK TRANSACTION 语句的 transaction_name 参数引用一组命名的嵌套事务的内层事务是非法的,transaction_name 只能引用最外部事务的事务名。如果在一组嵌套事务的任意级别执行使用外部事务名称的 ROLLBACK TRANSACTION transaction_name 语句,那么所有的嵌套事务都将回滚。如果在一组嵌套事务的任意级别执行没有 transaction_name 参数的 ROLLBACK WORK 或 ROLLBACK TRANSACTION 语句,那么它将回滚所有嵌套事务,包括最外部事务。

@@TRANCOUNT 函数记录当前事务的嵌套级。每个 BEGIN TRANSACTION 语句使 @@TRANCOUNT 加 1。每个 COMMIT TRANSACTION 或 COMMIT WORK 语句使 @@TRANCOUNT 减 1。没有事务名的 ROLLBACK WORK 或 ROLLBACK TRANSACTION 语句将回滚所有嵌套事务,并使 @@TRANCOUNT 减小到 0。使用一组嵌套事务中最外部事务的事务名称的 ROLLBACK TRANSACTION 将回滚所有嵌套事务,并使 @@TRANCOUNT 减到 0。在无法确定是否已经在事务中时,可以用 SELECT @@TRANCOUNT 语句确定 @@TRANCOUNT 是 1 还是更大。如果 @@TRANCOUNT 是 0,则表明不在事务中。

如何解决嵌套显式事务的问题,我举了一个例子:

None.gif
None.gif
-- create a table for testing
None.gif
None.gifCreate Table T1(v 
int check (v<100))     -- v必须小于100
None.gif
None.gif
--create first proc to insert data
None.gif
None.gifCreate Proc InnerTrans
None.gif
AS
None.gifBegin
None.gif    begin tran tran1
None.gif    insert into T1 values(
1-- this should be ok
None.gif    
if @@error<>0
None.gif        begin
None.gif            rollback tran tran1
None.gif            return 
-1
None.gif        
end
None.gif    
None.gif    insert into T1 values(
200-- 违反了约束
None.gif    
if @@error<>0
None.gif        begin
None.gif            rollback tran tran1
None.gif            return 
-1
None.gif        
end
None.gif    commit tran tran1
None.gif    return 
1
None.gif    
--ok here
None.gif
End
None.gif
None.gifCreate Proc OuterTran
None.gif
AS
None.gifBegin
None.gif    begin tran tran2
None.gif    insert into T1 values(
2)        -- ok now
None.gif    declare  @invokecode 
int
None.gif    exec @invokecode
=innerTrans
None.gif    
if(@invokecode=-1)        
None.gif        rollback tran tran2
None.gif    
else
None.gif        commit tran tran2
None.gif    
None.gif
End
None.gif
None.gif
select * from T1
None.gifexec innerTrans    
-- worked ok
None.gifexec OuterTran    
--does not work
None.gif
None.gif
-- How to Modify?
None.gif
None.gif
None.gifalter Proc InnerTrans
None.gif
AS
None.gifBegin
None.gif    begin tran tran1
None.gif    save tran ttt    
--savepoint here
None.gif    insert into T1 values(
1-- this should be ok
None.gif    
if @@error<>0
None.gif        begin
None.gif            rollback tran ttt
None.gif            commit tran tran1
None.gif             return 
-1
None.gif        
end
None.gif    
None.gif    insert into T1 values(
200-- 违反了约束
None.gif    
if @@error<>0
None.gif        begin
None.gif            rollback tran ttt
None.gif            commit tran tran1
None.gif            return 
-1
None.gif        
end
None.gif    commit tran tran1
None.gif    return 
1
None.gif    
--ok here
None.gif
End
None.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值