加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – 如何从一个存储过程启动3个存储过程时回滚

发布时间:2021-01-14 18:03:15 所属栏目:编程 来源:网络整理
导读:我有一个存储进程,只在个中执行3个存储进程.假如主SP乐成,我只行使1个参数来存储. 假如第一个存储进程在主存储进程中正常事变,但第二个存储进程失败,那么它会自动回滚主SP中的全部SP照旧我必需做一些呼吁? 这是我的措施: CREATE PROCEDURE [dbo].[spSavesom

>在每个proc的顶部,DECLARE @InBestedTransaction BIT;
>取代简朴的BEGIN TRAN,执行:

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;.
>在触发器内部,XACT_ABORT隐式配置为ON.这会导致触发器中的任何错误打消触发触发器的整个DML语句.
>您应始终举办恰当的错误处理赏罚,尤其是在行使事宜时. SQL Server 2005中引入的TRY … CATCH结构提供了一种处理赏罚险些全部环境的要领,这是在每个语句之后对@@ ERROR举办测试的一种受接待的改造,这对批量中止错误没有多大辅佐.

然而,TRY …… CATCH引入了一个新的“状态”.当不行使TRY … CATCH结构时,假如您有一个勾当的事宜而且产生错误,那么可以回收几个路径:

> XACT_ABORT OFF和语句中止错误:事宜仍处于勾当状态,并继承处理赏罚下一个语句(假若有).
> XACT_ABORT OFF和大大都批量中止错误:事宜处于勾当状态,处理赏罚将继承举办下一批处理赏罚(假若有).
> XACT_ABORT OFF和某些批量中止错误:回滚事宜并继承处理赏罚下一批(假若有).
> XACT_ABORT ON和任何错误:回滚事宜并继承处理赏罚下一批(假若有).

可是,当行使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

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读