http://wang2855.spaces.live.com/  我的BLOG.
CREATE PROCEDURE SP_TEST
AS
  BEGIN        
          BEGIN TRAN
   INSERT INTO DIC_PAY_TYPE
      (PAY_ID, PAY_NAME)
   VALUES ('AA', 'SDF')   ---A 语句 (错误语句)

           
   INSERT INTO DIC_FEE(id,FEE_TYPE,FEE_YEAR,MONEY) VALUES (1,'AA',1,500)
  --B语句 (正确语句)
   IF @@ERROR<>0
   BEGIN
     ROLLBACK TRAN
     PRINT 'ROLLBACK'
   END
   ELSE
   BEGIN
     COMMIT TRAN
     PRINT 'COMMIT'
   ENDEND一开始我认为这样写在一个存储过程中是没问题的,后来一个同事认为,@@Error是指最后一条语句的错误,经过查找也是这么回事。她认为需要对每条语句的@@Error判断,
经过测试后,发现当A语句执行失败的时候根本执行不到下面
的判断,而且事务自动回滚。而当我把B语句写到A语句前面,则能执行到A语句,
结果也是自动回滚。
那么我的红字部分判断, IF @@ERROR<>0就是多余的。
我只需要Commit Tran(提交所有成功的).这个是必须的,否则会Lock Table.进一步研究后发现:SET IMPLICIT_TRANSACTIONS off
是用来设置是否开启隐含事务,如果开启后,自动提交(也就是说,sqlserver自动
在你的语句前面加begin tran,后面加commit tran 和oracle 一样,如果你再写begin tran
也必须再写commit)
 
纠正上面的错误结论:
当A语句执行失败的时候根本执行不到下面
发现当出现的错误比较非数据错误,比如是数字字段却插入字符内容,这些错误是会马上跳出,当是数据错误,比如主键冲突,约束,等等这些错误还是会往下执行的.进一步发现,Commit Tran如果提交时有错误,系统会自动RollBack,所以和Oracle一样,
一般不需要RollBack.(大家可以讨论)

解决方案 »

  1.   

    个人觉得sql的事务不怎么样,达不到同生共死的效果呢
      

  2.   

    语法
    SET XACT_ABORT { ON | OFF }注释
    当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。
      

  3.   

    用 @@ERROR 检测多条语句的成功,一般如你同事所说一条检测
    CREATE PROCEDURE SP_TEST
    AS
      BEGIN  
           DECLARE @Insert1_error int, @Insert2_error int
          
              BEGIN TRAN
       INSERT INTO DIC_PAY_TYPE
          (PAY_ID, PAY_NAME)
       VALUES ('AA', 'SDF')   ---A 语句 (错误语句)
    SELECT @Insert1_error = @@ERROR           
       INSERT INTO DIC_FEE(id,FEE_TYPE,FEE_YEAR,MONEY) VALUES (1,'AA',1,500)
    Select @Insert2_error=@@ERROR
      --B语句 (正确语句)
       IF @Insert1_error<>0 Or @Insert2_error<>0
       BEGIN
         ROLLBACK TRAN
         PRINT 'ROLLBACK'
       END
       ELSE
       BEGIN
         COMMIT TRAN
         PRINT 'COMMIT'
       ENDEND一般不需要RollBack??我认为还是要吧,具体无测试
      

  4.   

    sql server 中存储过程本身做为一个事务来处理(自动开始事务 结束后提交或撤消事务)
    如果其中有些语句出现错误(错误大于一定级别的)会自动撤消所有语句的改动
    有。但有些用户级别的错误需要自己判断。
    可以save tran
       出现错误后
      rollback tran