在sqlserver中使用事务的注意事项

       这两天在项目开发中遇到一些业务逻辑需要进行大量的计算和数据的一致性,因此使用到sql事务和try catch。在项目需求中,多个业务逻辑单元分别写在对应的存储过程中,并进行事务控制,同时需要一个总调用的存储过程pro_contry,这个总调用de 存储过程pro_contry通过事务封装上面的所有业务逻辑单元存储过程,当其中任何一个存储过程出现错误时,全部回滚。pro_contry调用过程中发现同时有事务嵌套,又有try catch嵌套。在测试的过程中发现各种离奇的错误现记录如下,

       第一个错误:

              错误描述:错误号:      3930, 错误严重级别:        16, 错位状态:         1, 错误存储过程和触发器名称:PRO_A_LogicUnit, 错误行号:       150, 错误实际信息:当前事务无法提交,而且无法支持写入日志文件的操作。请回滚该事务。

              错误原因:由于pro_contry 和PRO_A_LogicUnit 中同时使用了try catch捕获错误。

             解决方法:将子存储过程PRO_A_LogicUnit的try catch取消,将错误由上一级抛出处理

      

      第二个错误

SAVE tran @tranName
EXEC Pro_Score_CountEverySubjectStandardRate 130

             错误描述:当前事务无法提交,而且无法回滚到保存点。请回滚整个事务。

             错误原因:由于在pro_contry和PRO_A_LogicUnit同时有事务处理,当PRO_A_LogicUnit中出现错误回滚 进行rollback,事务保存点设置错误导致。

             解决方法:应该先判断是否已经存在事务,若已经存在则设置事务保存点,不存在创建事务处理

             DECLARE @tranCounter  INT

            DECLARE @tranName      VARCHAR(20)

            SET @tranCounter  = @@TRANCOUNT

            SET @tranName    = 'tran'

            IF @tranCounter = 0

                      BEGIN

                              BEGIN TRAN @tranName

                      END

            ELSE

                     BEGIN

                             SAVE TRAN @tranName

                     END

        第三个错误
        在内部嵌套事务 ROLLBACK tran

       错误描述: 错误号:       266, 错误严重级别:        16, 错位状态:         2, 错误存储过程和触发器名称:PRO_A_LogicUnit, 错误行号:         0, 错误实际信息:EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 1,当前计数 = 0。

      错误原因:在事务中begin tran 后@@tranCount 会加1,当commit tran 后会减1,而rollback tran后 @@tranCount = 0,因此在事务嵌套中必须保存begin tran几次对应的commit tran 也几次



        第三个错误

                错误描述:

嵌套事务中指定 ROLLBACK tran @tranName

               错误号:      6401, 错误严重级别:        16, 错位状态:         1, 错误存储过程和触发器名称:Pro_Score_CountEverySubjectStandardRate, 错误行号:       148, 错误实际信息:无法回滚 countEverySubjectStandardRate。找不到该名称的事务或保存点。







不要使用嵌套事务
不能过分使用嵌套事务,非常麻烦


当SET XACT_ABORT ON 后try catch 中遇到程序错误时catch 会事务回滚


使用save tran 替代嵌套tran

DECLARE @TranCounter INT;
    SET @TranCounter = @@TRANCOUNT;
    

    --当只有一个事务的时候进行回滚,否则嵌套事务由外面的rollback进行回滚



http://hi.baidu.com/duobaiduodu/item/79375ed7b0d60ac71a72b4f6

http://msdn.microsoft.com/zh-cn/library/ms189797.aspx

http://msdn.microsoft.com/zh-cn/library/ms175976.aspx

http://msdn.microsoft.com/zh-cn/library/ms179296%28v=SQL.100%29.aspx

http://wenku.baidu.com/view/8d1d3ded6294dd88d0d26bd0.html

http://msdn.microsoft.com/en-us/library/ms179296%28v=sql.105%29.aspx

http://blog.csdn.net/wufeng4552/article/details/6317515

http://blog.sina.com.cn/s/blog_496cf0e70100i0em.html

http://blog.csdn.net/xmzhaoym/article/details/5120372

http://www.cnblogs.com/yangpei/archive/2010/10/07/1894408.html


转载于:https://www.cnblogs.com/wala-wo/archive/2012/12/27/5119380.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值