sql-server – 如何从一个存储过程启动3个存储过程时回滚
>在每个proc的顶部,DECLARE @InBestedTransaction BIT; IF (@@TRANCOUNT = 0) BEGIN SET @InNestedTransaction = 0; BEGIN TRAN; -- only start a transaction if not already in one END; ELSE BEGIN SET @InNestedTransaction = 1; END; >取代简朴的COMMIT,执行: IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0) BEGIN COMMIT; END; >取代简朴的ROLLBACK,执行: IF (@@TRANCOUNT > 0 AND @InNestedTransaction = 0) BEGIN ROLLBACK; END; 无论事宜是在SQL Server中启动照旧在应用层启动,此要领都应该沟通. 有关TRY … CATCH布局中此事宜处理赏罚的完备模板,请参阅以下DBA.SE题目的谜底:Are we required to handle Transaction in C# Code as well as in stored procedure. 逾越“基本”,还必要留意一些特另外买卖营业渺小不同: >默认环境下,大大都环境下,产生错误时,事宜不会自动回滚/打消.只要您有恰当的错误处理赏罚并本身挪用ROLLBACK,这凡是不是题目.可是,偶然工作变得伟大,譬喻在批量中止错误的环境下,可能在行使OPENQUERY(或一样平常的链接处事器)时,而且长途体系上产生错误.固然大大都错误都可以行使TRY … CATCH来捕捉,可是有两个错误不能被捕捉(不记适合前哪些错误 – 研究).在这些环境下,必需行使SET XACT_ABORT ON才气正确回滚事宜. SET XACT_ABORT ON使SQL Server当即回滚任何事宜(假如一个处于勾当状态)并在产生任何错误时中止批处理赏罚.此配置存在于SQL Server 2005之前,它引入了TRY … CATCH结构.在大大都环境下,TRY … CATCH处理赏罚大大都环境,因此大大都都废弃了对XACT_ABORT ON的需求.可是,当行使OPENQUERY(也许尚有一个我今朝不记得的场景)时,您如故必要行使SET XACT_ABORT ON;. 然而,TRY …… CATCH引入了一个新的“状态”.当不行使TRY … CATCH结构时,假如您有一个勾当的事宜而且产生错误,那么可以回收几个路径: > XACT_ABORT OFF和语句中止错误:事宜仍处于勾当状态,并继承处理赏罚下一个语句(假若有). 可是,当行使TRY … CATCH时,批量中止错误不会中止批处理赏罚,而是将节制转移到CATCH块.当XACT_ABORT为OFF时,买卖营业在绝大大都时刻内如故处于勾当状态,您必要COMMIT,可能很也许必要ROLLBACK.可是当碰着某些批量中止错误(譬喻行使OPENQUERY)或XACT_ABORT为ON时,事宜将处于新状态,“不行拒绝”.在这种状态下你不能COMMIT,也不能做任何DML操纵.您所能做的就是ROLLBACK和SELECT语句.可是,在这种“不行注册”状态下,事宜在产生错误时回滚,而且发出ROLLBACK只是一种情势,但必需完成. 函数XACT_STATE可用于确定事宜是处于勾当状态,不行节制照旧不存在.提议(至少某些人)在CATCH块中搜查此成果以确定功效是否为-1(即不行拒绝),而不是测试@@ TRANCOUNT> 0.可是在XACT_ABORT开启的环境下,这应该是独一也许存在的状态,因此好像测试@@ TRANCOUNT> 0和XACT_STATE()<> 0是等价的.另一方面,当XACT_ABORT为OFF而且存在勾当事宜时,则CATCH块中也许具有1或-1的状态,这应承发出COMMIT而不是ROLLBACK(尽量云云,假如事宜是可提交的,那么当有人想要COMMIT时,我们就不会想到这种环境.有关在XACT_ABORT ON的CATCH块中行使XACT_STATE()的更多信息和研究可以在我对以下DBA.SE题目的谜底中找到:In what cases a transaction can be committed from inside the CATCH block when XACT_ABORT is set to ON?.请留意XACT_STATE()存在一个小错误导致它错误地返回1在某些环境下:XACT_STATE() returns 1 when used in SELECT with some system variables but without FROM clause 关于原始代码的声名: >您可以删除提供应买卖营业的名称,由于它没有任何辅佐.>每个EXEC挪用都不必要BEGIN和END (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |