事务内部的T-SQL EXEC命令

时间:2012-06-21 12:48:02

标签: sql-server tsql transactions

我需要使用公共EXEC命令从另一个执行存储过程。 我需要确定,所有sql语句都将在事务中。

BEGIN TRANSACTION
BEGIN TRY   

    SET @Esercizio = (SELECT ESERCIZIO_OBIETTIVI_CONSUNTIVARE from TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE)
    SET @TipoProcesso = (SELECT ISNULL(TipoProcesso, 'middle') from TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE)

    DELETE FROM TB_SCHEDE WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE
    DELETE FROM TB_SCHEDE_AUTOVAL WHERE MATRICOLA = @iMATRICOLA and COD_VALUTAZIONE = @iCOD_VALUTAZIONE
    DELETE FROM TB_OBIETTIVI WHERE MATRICOLA = @iMATRICOLA and ESERCIZIO =  @Esercizio
    DELETE FROM TB_OBIETTIVI_AUTOVAL WHERE MATRICOLA = @iMATRICOLA and ESERCIZIO =  @Esercizio

    EXEC AnotherStore @iCOD_VALUTAZIONE, @iMATRICOLA, @TipoProcesso
    COMMIT TRANSACTION

END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION
END CATCH

如果AnotherStore过程抛出异常,数据库引擎是否确保从调用者存储过程回滚?

希望明确。

2 个答案:

答案 0 :(得分:2)

有关事务存在时异常处理的示例,请参阅Exception handling and nested transactions

create procedure [usp_my_procedure_name]
as
begin
    set nocount on;
    declare @trancount int;
    set @trancount = @@trancount;
    begin try
        if @trancount = 0
            begin transaction
        else
            save transaction usp_my_procedure_name;

        -- Do the actual work here

lbexit:
        if @trancount = 0   
            commit;
    end try
    begin catch
        declare @error int, @message varchar(4000), @xstate int;
        select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
        if @xstate = -1
            rollback;
        if @xstate = 1 and @trancount = 0
            rollback
        if @xstate = 1 and @trancount > 0
            rollback transaction usp_my_procedure_name;

        raiserror ('usp_my_procedure_name: %d: %s', 16, 1, @error, @message) ;
    end catch   
end

答案 1 :(得分:1)

简单的答案是肯定的是它将回滚调用者存储过程的更改,但是如果你在其他存储过程中有事务,那就考虑一下,如果是这种情况,有可能事情不像你期望的那样。 ROLLBACK会影响所有交易,尽管这可能是您想要的。您可以在捕获中使用@@TRANCOUNT并确定是否要回滚整个内容,Savepoints.

BEGIN TRANSACTIONCOMMITROLLBACK之间的所有到数据库都是事务的一部分,如果有任何行出错,请控制将被路由到将回滚事务的CATCH块。 像表变量这样的东西将超出此范围而不会回滚。正如@David Brabant所说,BEGIN TRANSACTION应该在BEGIN TRY块中。