• 嵌套事务的问题


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

    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,则表明不在事务中。

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


    -- create a table for testing

    Create Table T1(v 
    int check (v<100))     -- v必须小于100

    --create first proc to insert data

    Create Proc InnerTrans
    AS
    Begin
        begin tran tran1
        insert into T1 values(
    1-- this should be ok
        
    if @@error<>0
            begin
                rollback tran tran1
                return 
    -1
            
    end
        
        insert into T1 values(
    200-- 违反了约束
        
    if @@error<>0
            begin
                rollback tran tran1
                return 
    -1
            
    end
        commit tran tran1
        return 
    1
        
    --ok here
    End

    Create Proc OuterTran
    AS
    Begin
        begin tran tran2
        insert into T1 values(
    2)        -- ok now
        declare  @invokecode 
    int
        exec @invokecode
    =innerTrans
        
    if(@invokecode=-1)        
            rollback tran tran2
        
    else
            commit tran tran2
        
    End

    select * from T1
    exec innerTrans    
    -- worked ok
    exec OuterTran    
    --does not work

    -- How to Modify?


    alter Proc InnerTrans
    AS
    Begin
        begin tran tran1
        save tran ttt    
    --savepoint here
        insert into T1 values(
    1-- this should be ok
        
    if @@error<>0
            begin
                rollback tran ttt
                commit tran tran1
                 return 
    -1
            
    end
        
        insert into T1 values(
    200-- 违反了约束
        
    if @@error<>0
            begin
                rollback tran ttt
                commit tran tran1
                return 
    -1
            
    end
        commit tran tran1
        return 
    1
        
    --ok here
    End
  • 相关阅读:
    linux下netstat命令详解
    linux下strace命令详解
    /proc/uptime
    趣味理解网关、路由等概念
    OPENCV运行的问题,自带的程序可以运行,但是自己制作的QT报错
    第九章 MIZ702 ZYNQ片上ADC的使用
    第四章 MIZ701 ZYNQ制作UBOOT固化程序
    第三章 VIVADO 自定义IP 流水灯实验
    第一章 MIZ701 VIVADO 搭建SOC最小系统HelloWorld
    Zynq-7000 MiZ701 SOC硬件使用手册
  • 原文地址:https://www.cnblogs.com/huqingyu/p/145710.html
Copyright © 2020-2023  润新知