Sql server 使用嵌套事务执行查询时出错

Sql server 使用嵌套事务执行查询时出错,sql-server,nested-transactions,Sql Server,Nested Transactions,我在尝试执行下面的查询时遇到错误 if exists (select null from sys.sysobjects where type='P' and name = 'myProc') drop PROCEDURE myProc go create procedure myProc as begin set nocount on set xact_abort on begin try declare @trancount int = @@

我在尝试执行下面的查询时遇到错误

if exists (select null from sys.sysobjects where type='P' and name = 'myProc')
    drop PROCEDURE myProc
go

create procedure myProc
as
begin
    set nocount on
    set xact_abort on

    begin try
        declare @trancount int = @@trancount

        if @trancount = 0
            begin tran
        else
            save tran MySave

        raiserror ('123213123',16,1)

        if @trancount = 0
            commit
    end try 
    begin catch
        if @trancount = 0
            rollback
        else
            if XACT_STATE() = 1
                rollback tran MySave
            else
                rollback    
    end catch
end
go

begin tran
    EXEC myProc

if @@TRANCOUNT >0
    rollback
错误是

EXECUTE后的事务计数表示BEGIN和COMMIT语句的数量不匹配。上一次计数=1,当前计数=0

我读过很多关于类似问题的话题,但到目前为止还不清楚我的问题的原因是什么。 有谁能解释一下我为什么会这样,我应该怎么做才能避免呢。 提前谢谢

upd。我可以像这样简化MyProc的代码

create procedure myProc
as
begin
    set nocount on
    set xact_abort on

    begin try
        begin tran
           raiserror ('123213123',16,1)
        commit
    end try 
    begin catch
        rollback
    end catch
end
go
它不能解决我的问题。出现相同的错误

请尝试以下操作:

ALTER PROCEDURE myProc
AS
    BEGIN
        SET NOCOUNT ON
        SET XACT_ABORT ON

        BEGIN TRY
            DECLARE @trancount INT = @@trancount

            IF @trancount = 0
                BEGIN TRAN
            ELSE
                SAVE TRAN MySave

            RAISERROR ('123213123',16,1)

            IF @trancount = 0
                COMMIT
        END TRY 
        BEGIN CATCH
            IF XACT_STATE() <> 0
                AND @trancount = 0
                ROLLBACK TRANSACTION;
        END CATCH
    END
GO

BEGIN TRAN
EXEC myProc


IF @@TRANCOUNT > 0
    ROLLBACK

trancount是MyProc处理之前的事务计数。如果trancount等于0,则启动trancaction begin tran,然后,如果发生错误,则回滚它;如果@trancount>0,则表示我已在外部事务中。所以我提出了一个保存点@Giorgi Nakeuri,是的,它是有效的。但我觉得这不是我真正想要的,在我们继续之前,你或其他人能给我举个例子吗,当我进入XACT_状态的catch block=1@zagrr,注释行-将XACT_中止设置为ON