这两天在项目开发中遇到一些业务逻辑需要进行大量的计算和数据的一致性,因此使用到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