T-SQL:从外部存储过程提交嵌套存储过程的操作

时间:2019-10-29 10:10:55

标签: tsql stored-procedures transactions commit

我正在使用嵌套存储过程。 Begin事务和commit / rollback语句在外部SP中。我能否对嵌套SP中发生的所有数据库操作都提交到外部SP中?目前看来,它不能像这样工作。交易上有任何配置允许吗?

ALTER procedure [dbo].[OuterStoredProcedure]
as
   begin
       declare @nRC int
       SET NOCOUNT ON

       begin transaction

       execute @nRC=InnerStoredProcedure /*includes update statements*/

        if (@nRC <> 1)
            rollback transaction
        else
            commit transaction
   end

1 个答案:

答案 0 :(得分:1)

我已经为您准备了以下考试。如您所见,如果嵌套过程返回0(作为错误),我们可以在第一个过程(父过程)中进行回滚

CREATE TABLE test1010
(
    ID Int identity (1,1),
    Name nvarchar(20)
)
GO

--DROP PROCEDURE dbo.A1
CREATE PROCEDURE dbo.A1
    @name nvarchar(20)
AS
    BEGIN
        INSERT INTO test1010 VALUES (@name)
        return 0
    END
GO

--DROP PROCEDURE dbo.AA
CREATE PROCEDURE dbo.AA
    @name1 nvarchar(20)
AS
    BEGIN
        DECLARE @nRC INT;
        SET NOCOUNT ON;

        BEGIN TRANSACTION;
        EXECUTE @nRC = dbo.A1 @name = @name1;
        IF(@nRC <> 1)
            ROLLBACK TRANSACTION;
        ELSE
            COMMIT TRANSACTION;
    END;
GO


SELECT * FROM test1010
GO
EXECUTE dbo.AA  @name1 = 'aa'
GO
SELECT * FROM test1010

enter image description here

还有另一件事。在每个过程中,我们都必须检查交易数量。如果没有交易,则将其打开;如果有交易,则将其保存。最后,我们检查是否打开了事务,如果没有,则提交它,然后让父过程处理事务。

您可以看到我的答案here

CREATE PROCEDURE Ardi_Sample_Test  
    @InputCandidateID INT  
AS  
    DECLARE @TranCounter INT;  
    SET @TranCounter = @@TRANCOUNT;  
    IF @TranCounter > 0  
        SAVE TRANSACTION ProcedureSave;  
    ELSE  
        BEGIN TRANSACTION;  
    BEGIN TRY  

        /*
        <Your Code>
        */

        IF @TranCounter = 0  
            COMMIT TRANSACTION;  
    END TRY  
    BEGIN CATCH  
        IF @TranCounter = 0  
            ROLLBACK TRANSACTION;  
        ELSE  
            IF XACT_STATE() <> -1  
                ROLLBACK TRANSACTION ProcedureSave;  

        DECLARE @ErrorMessage NVARCHAR(4000);  
        DECLARE @ErrorSeverity INT;  
        DECLARE @ErrorState INT;  
        SELECT @ErrorMessage = ERROR_MESSAGE();  
        SELECT @ErrorSeverity = ERROR_SEVERITY();  
        SELECT @ErrorState = ERROR_STATE();  

        RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);  
    END CATCH  
GO  

在您的过程中始终使用此模式。

相关问题