一个存储过程有3000多行语句 我在里面建了三个事务 create procedure aaaas statement
.语句
.语句
.语句
.语句
statementif-----------重要更新
exists (condition)BEGIN TRANSACTION FeeClac1statement1
.语句
.语句
.语句
.语句
statement1IF(@@ERROR <> 0)
BEGIN
    ROLLBACK TRANSACTION FeeClac1
    RETURN -1
END-----------重要更新end
BEGIN TRANSACTION FeeClac2statement2
.语句
.语句
.语句
.语句
statement2IF(@@ERROR <> 0)
BEGIN
    ROLLBACK TRANSACTION FeeClac2
    RETURN -1
END
BEGIN TRANSACTION FeeClac3statement3
.语句
.语句
.语句
.语句
statement3IF(@@ERROR <> 0)
BEGIN
    ROLLBACK TRANSACTION FeeClac3
    ROLLBACK TRANSACTION FeeClac2
    RETURN -1
ENDCOMMIT   TRANSACTION我的意图是: 
在statement1语句群执行失败时,回滚事务FeeClac1,结束存储过程; 
若statement1语句群执行成功,当statement2语句群执行失败时,则回滚事务FeeClac1和事务FeeClac2,结束存储过程; 
若statement1和statement2语句群都执行成功,而statement3语句群执行失败时,则回滚事务FeeClac1和事务FeeClac2和事务FeeClac3,结束存储过程。 
如果statement1和statement2和statement3语句群都执行成功,就提交三个事务(事务FeeClac1和事务FeeClac2和事务FeeClac3)。 请问上面写的对不对? 
不对的话,应该怎么写?? 
谢谢

解决方案 »

  1.   

    最后的commit transaction
    ->>>>commit transaction FeeClac3
    commit transaction FeeClac2
    commit transaction FeeClac1
      

  2.   

    另外,rollback transaction 可不带事务名,这样只要一个rollback transaction
      

  3.   

    create procedure aaaas statement
    .语句
    .语句
    .语句
    .语句
    statementif-----------重要更新
    exists (condition)BEGIN TRANSACTION FeeClac1statement1
    .语句
    .语句
    .语句
    .语句
    statement1IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    END-----------重要更新end
    BEGIN TRANSACTION FeeClac2statement2
    .语句
    .语句
    .语句
    .语句
    statement2IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    END
    BEGIN TRANSACTION FeeClac3statement3
    .语句
    .语句
    .语句
    .语句
    statement3IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    ENDcommit   transaction   FeeClac3 
    commit   transaction   FeeClac2 
    commit   transaction   FeeClac1
      

  4.   


    create procedure aaaas statement
    .语句
    .语句
    .语句
    .语句
    statementif-----------重要更新
    exists (condition)BEGIN TRANSACTION FeeClac1statement1
    .语句
    .语句
    .语句
    .语句
    statement1IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    END-----------重要更新end
    BEGIN TRANSACTION FeeClac2statement2
    .语句
    .语句
    .语句
    .语句
    statement2IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    END
    BEGIN TRANSACTION FeeClac3statement3
    .语句
    .语句
    .语句
    .语句
    statement3IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        
        RETURN -1
    ENDCOMMIT   TRANSACTION FeeClac3
    COMMIT   TRANSACTION FeeClac2
    COMMIT   TRANSACTION FeeClac1
      

  5.   

    如果BEGIN TRANSACTION FeeClac2statement2
    .语句
    .语句
    .语句
    .语句
    statement2IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION FeeClac2
        RETURN -1
    ENDCOMMIT   TRANSACTION
    ......ROLLBACK TRANSACTION FeeClac2只能回滚到 FEECLAC2 事务 但是 FEECLAC1 还会继续执行 到 COMMIT   TRANSACTION提交
      

  6.   

    关键是有第一个事务包含在IF语句里
    这个事务有可能会不被执行
    在不被执行的情况下
    COMMIT   TRANSACTION FeeClac3
    COMMIT   TRANSACTION FeeClac2
    COMMIT   TRANSACTION FeeClac1------这一步写出来就会报错的'ROLLBACK TRANSACTION FeeClac2 只能回滚到 FEECLAC2 事务 
    但是 FEECLAC1 还会继续执行 到 COMMIT   TRANSACTION提交'是啊
    但是 事务FeeClac1 在一个IF ...END语句里
    不能保证每次都执行,所以不能写成
    BEGIN TRANSACTION FeeClac2statement2
    .语句
    .语句
    .语句
    .语句
    statement2IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION FeeClac2
        ROLLBACK TRANSACTION FeeClac1
        RETURN -1
    END
    BEGIN TRANSACTION FeeClac3statement3
    .语句
    .语句
    .语句
    .语句
    statement3IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION FeeClac3
        ROLLBACK TRANSACTION FeeClac2
        ROLLBACK TRANSACTION FeeClac1
        RETURN -1
    END
      

  7.   

    第一个为什么要放里if 里面呀,加到if 前面去呀,不管条件满足否,都开始事务
      

  8.   

    create procedure aaaas statement
    .语句
    .语句
    .语句
    .语句
    statementif-----------重要更新
    exists (condition)BEGIN TRANSACTION FeeClac1statement1
    .语句
    .语句
    .语句
    .语句
    statement1IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    END-----------重要更新end
    BEGIN TRANSACTION FeeClac2statement2
    .语句
    .语句
    .语句
    .语句
    statement2IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    END
    BEGIN TRANSACTION FeeClac3statement3
    .语句
    .语句
    .语句
    .语句
    statement3IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    ENDCOMMIT   TRANSACTION
    如果这样写就应该是最正确的是吧????
      

  9.   

    '第一个为什么要放里if   里面呀,加到if   前面去呀,不管条件满足否,都开始事务'
    其实可以把三个事务写成一个事务的之所以这样写,只是为了要提高执行效率,缩短存储过程的执行时间
    由于IF里的语句太多,临时表也太多,(临时表里的内容是没有必要去回滚的,所以就不想让事务因为检查他们的有效性而浪费资源)所以就把事务FeeClac1写在了IF语句里的关键部位了,只把对几个结果表的插入操作设成了事务。
      

  10.   

    或是COMMIT   TRANSACTION 换成COMMIT   更合理因为你如果定义了事务名称 ,嵌套的 BEGIN...COMMIT 或 BEGIN...ROLLBACK 语句的最好对上使用事务名
      

  11.   

    create procedure aaaas statement
    .语句
    .语句
    .语句
    .语句
    statement
    set xact_abort on     --加这句BEGIN TRAN            --开始事务if-----------重要更新
    exists (condition)statement1
    .语句
    .语句
    .语句
    .语句
    statement1IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION    --出错回滚事务,其实,如果不加这句的回滚,系统一旦出错,也会自动回滚,因为设置了set xact_abort on
        RETURN -1
    END-----------重要更新endstatement2
    .语句
    .语句
    .语句
    .语句
    statement2IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION    --出错回滚事务,其实,如果不加这句的回滚,系统一旦出错,也会自动回滚,因为设置了set xact_abort on
        RETURN -1
    ENDstatement3
    .语句
    .语句
    .语句
    .语句
    statement3IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION    --出错回滚事务,其实,如果不加这句的回滚,系统一旦出错,也会自动回滚,因为设置了set xact_abort on
        RETURN -1
    ENDCOMMIT   TRAN          --提交事务
      

  12.   

    create procedure aaaas statement
    .语句
    .语句
    .语句
    .语句
    statementIF
    EXISTS (condition...)BEGIN TRANSACTION FeeClac1statement1
    .语句
    .语句
    .语句
    .语句
    statement1IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    ENDEND
    BEGIN TRANSACTION FeeClac2statement2
    .语句
    .语句
    .语句
    .语句
    statement2IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    END
    BEGIN TRANSACTION FeeClac3statement3
    .语句
    .语句
    .语句
    .语句
    statement3IF(@@ERROR <> 0)
    BEGIN
        ROLLBACK TRANSACTION 
        RETURN -1
    ENDCOMMIT   TRANSACTION  FeeClac3
    COMMIT   TRANSACTION  FeeClac2
    IF(@@TRANCOUNT<>0)
    COMMIT   TRANSACTION  FeeClac1谢谢大家的回答最后我打算就这么写了
      

  13.   

    其实可以把三个事务写成一个事务的 之所以这样写,只是为了要提高执行效率,缩短存储过程的执行时间 
    由于IF里的语句太多,临时表也太多,(临时表里的内容是没有必要去回滚的,所以就不想让事务因为检查他们的有效性而浪费资源) 所以就把事务FeeClac1写在了IF语句里的关键部位了,只把对几个结果表的插入操作设成了事务。 

    并没有看出你这样写会提高性能,你这样写只能延长存储过程的执行时间,而且让以后维护你这个存储过程的人还得来论坛上来问为什么你会这么写存储过程。 :) 首先你来回判断回滚和提交的时机本身就会耗费时间和维护的工作量,SQL Server嵌套事务本身就是毫无意义的。你的临时表的理由也不够充分,你可以判断临时表后再开始事务呀。一个事务就搞定了!不要用三个事务。
      

  14.   

    '你可以判断临时表后再开始事务呀。一个事务就搞定了!不要用三个事务。' 
    IF END 不是每次都会执行的。要考虑不执行的情况的。就无法只写一个事务create procedure aaaas statement
    .语句
    .语句
    .语句
    .语句
    statementIF
    EXISTS (condition...)statement
    .语句
    .语句
    .语句
    .语句
    statementSET XACT_ABORT ONBEGIN TRANSACTION FeeClac1statement1
    .语句
    .语句
    .语句
    .语句
    statement1ENDSET XACT_ABORT ONBEGIN TRANSACTION FeeClac2statement2
    .语句
    .语句
    .语句
    .语句
    statement2
    statement3
    .语句
    .语句
    .语句
    .语句
    statement3COMMIT TRANSACTION  FeeClac2IF(@@ERROR<>0)
    ROLLBACK TRANSACTION  FeeClac1IF(@@TRANCOUNT<>0)
    COMMIT TRANSACTION  FeeClac1OVER结贴了非常感谢大家的热情帮助