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

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

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

我有一个存储进程,只在个中执行3个存储进程.假如主SP乐成,我只行使1个参数来存储.

假如第一个存储进程在主存储进程中正常事变,但第二个存储进程失败,那么它会自动回滚主SP中的全部SP照旧我必需做一些呼吁?

这是我的措施:

CREATE PROCEDURE [dbo].[spSavesomename] 
    -- Add the parameters for the stored procedure here

    @successful bit = null output
AS
BEGIN
begin transaction createSavebillinginvoice
    begin Try
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

   BEGIN 

   EXEC [dbo].[spNewBilling1]

   END

   BEGIN 

   EXEC [dbo].[spNewBilling2]

   END

   BEGIN 

   EXEC [dbo].[spNewBilling3]

   END 

   set @successful  = 1

   end Try

    begin Catch
        rollback transaction createSavesomename
        insert into dbo.tblErrorMessage(spName,errorMessage,systemDate) 
             values ('spSavesomename',ERROR_MESSAGE(),getdate())

        return
    end Catch
commit transaction createSavesomename
return
END

GO

办理要领

仅给出题目中表现的代码,并假设三个子进程中没有一个具有任何显式事宜处理赏罚,则是,将捕捉三个子进程中的任何一此中的错误而且CATCH块中的ROLLBACK将转动返来全部的事变.

可是这里有一些关于事宜的留意事项(至少在SQL Server中):

>无论您几多次拨打BEGIN TRAN,都只有一次真正的买卖营业(第一次)

>您可以定名一个事宜(就像您在此地方做的那样)而且该名称将呈此刻日记中,但定名仅对第一个/最外部事宜具故意义(由于同样,第一个事宜是事宜).
>每次挪用BEGIN TRAN时,无论是否定名,事宜计数器城市增进1.
>您可以通过SELECT @@ TRANCOUNT查察当前级别;
>当@@ TRANCOUNT为2或更高时发出的任何COMMIT呼吁都只能镌汰,一次镌汰一个事宜计数器.
>在@@ TRANCOUNT为1时发出COMMIT之前,没有任何工作产生
>以防上述信息未明晰指出:无论买卖营业级别怎样,都没有现实的买卖营业嵌套.

>生涯点应承在事宜中建设可除掉的事变子集.

>通过SAVE TRAN {save_point_name}呼吁建设/标志生涯点
>生涯点标志可以除掉的事变子集的开头,而不回滚整个事宜.
>生涯点名称不必是独一的,但多次行使沟通的名称仍会建设差异的生涯点.
>生涯点可以嵌套.
>无法提交生涯点.
>可以通过ROLLBACK {save_point_name}除掉生涯点. (以下更多内容)
>回滚生涯点将除掉在最近一次挪用SAVE TRAN {save_point_name}之后产生的任何事变,包罗在建设回滚之后建设的任何生涯点(因此“嵌套”).
>回滚生涯点对事宜计数/级别没有影响
>除了通过发出整个买卖营业的完备ROLLBACK之外,在初始SAVE TRAN之前完成的任何事变都无法除掉.
>只是要明晰:当@@ TRANCOUNT为2或更高时发出COMMIT对生涯点没有影响(由于在该计数器之外不存在高于1的事宜级别).

>您无法提交特定的定名事宜.事宜“名称”(假如与COMMIT一路提供)将被忽略,仅出于可读性而存在.
>没著名称的ROLLBACK将始终回滚全部事宜.
>行使名称发出的ROLLBACK必需对应于:

>第一个事宜,假设它被定名为:
假设没有行使沟通的事宜名称挪用SAVE TRAN,这将回滚全部事宜.
>“生涯点”(如上所述):
此举动将“除掉”自最近的SAVE TRAN {save_point_name}被挪用以来所做的全部变动.
>假如第一个事宜是a)定名而且b)已经发出了带有其名称的SAVE TRAN呼吁,那么该事宜名称的每个ROLLBACK将除掉每个生涯点,直到该名称没有剩余.之后,发出该名称的ROLLBACK将回滚全部事宜.
>譬喻,假设以下表现的次序运行以下呼吁:

BEGIN TRAN A -- @@TRANCOUNT is now 1
-- DML Query 1
SAVE TRAN A
-- DML Query 2
SAVE TRAN A
-- DML Query 3

BEGIN TRAN B -- @@TRANCOUNT is now 2
SAVE TRAN B
-- DML Query 4

此刻,假如您宣布(以下每个方案互相独立):

> ROLLBACK TRAN B一次:它将除掉“DML Query 4”. @@ TRANCOUNT如故是2.
> ROLLBACK TRAN B两次:它将除掉“DML Query 4”然后堕落,由于“B”没有响应的生涯点. @@ TRANCOUNT如故是2.
> ROLLBACK TRAN A一次:它将除掉“DML Query 4”和“DML Query 3”. @@ TRANCOUNT如故是2.
> ROLLBACK TRAN A两次:它将除掉“DML Query 4”,“DML Query 3”和“DML Query 2”. @@ TRANCOUNT如故是2.
> ROLLBACK TRAN三次:它将除掉“DML Query 4”,“DML Query 3”和“DML Query 2”.然后它将回滚整个事宜(剩下的就是“DML Query 1”). @@ TRANCOUNT此刻为0.
> COMMIT一次:@@ TRANCOUNT降为1.
> COMMIT一次然后ROLLBACK TRAN B一次:@@ TRANCOUNT降落到1.然后它将除掉“DML Query 4”(证明COMMIT没有做任何工作). @@ TRANCOUNT如故是1.

>买卖营业名称和生涯点名称:

>最多可包括32个字符
>被视为具有二进制排序法则(不像文档当前所述的区分巨细写),无论实例级别照旧数据库级别排序法则.
>有关具体信息,请参阅以下帖子的“买卖营业名称”部门:What’s in a Name?: Inside the Wacky World of T-SQL Identifiers

>存储进程自己不是隐式事宜.假如没有启动显式事宜,则每个查询都是隐式事宜.这就是为什么不必要环绕单个查询的显式事宜,除非也许有编程缘故起因来执行ROLLBACK,不然查询中的任何错误都是该查询的自动回滚.
>挪用存储进程时,它必需以@@ TRANCOUNT的值与挪用时沟通的方法退出.意思是,你不能:

>在proc中启动BEGIN TRAN而不提交它,祈望在挪用/父历程中提交.
>假如在挪用proc之前启动了显式事宜,则无法发出ROLLBACK,由于它会将@@ TRANCOUNT返回到0.

假如退出存储进程的事宜计数高于或低于它的注视时刻,则会呈现相同于以下内容的错误:

Msg 266,Level 16,State 2,Procedure YourProcName,Line 0
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = X,current count = Y.

>表变量与通例变量一样,不受事宜束缚.

关于在proc中举办事宜处理赏罚,可以独立挪用(因此必要事宜处理赏罚)或从其他proc挪用(因此不必要事宜处理赏罚):这可以通过几种差异的方法完成.

(编辑:湖南网)

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

热点阅读