Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server中的嵌套过程回滚?_Sql Server - Fatal编程技术网

Sql server SQL Server中的嵌套过程回滚?

Sql server SQL Server中的嵌套过程回滚?,sql-server,Sql Server,下面是外部和嵌套过程的代码 ALTER PROCEDURE dbo.NestedProcedure AS BEGIN SET XACT_ABORT OFF SET NOCOUNT ON BEGIN TRY DECLARE @trancount INT SET @trancount = @@TRANCOUNT IF @trancount = 0 BEGIN TRANSACTION ELS

下面是外部和嵌套过程的代码

ALTER PROCEDURE dbo.NestedProcedure
AS
BEGIN
    SET XACT_ABORT OFF
    SET NOCOUNT ON
    BEGIN TRY
        DECLARE @trancount INT
        SET @trancount = @@TRANCOUNT
        IF @trancount = 0
            BEGIN TRANSACTION
        ELSE 
            SAVE TRANSACTION NestedProcedure

            ALTER TABLE dbo.Table_2
            ALTER COLUMN Column3 VARCHAR
        IF @trancount = 0
            COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        SELECT XACT_STATE()
        DECLARE @error INT, @message VARCHAR(4000), @xstate INT;
        SELECT @error = ERROR_NUMBER(), @message = ERROR_MESSAGE();
        IF XACT_STATE() = -1
        BEGIN
            ROLLBACK
        END
        IF XACT_STATE() = 1 AND @trancount = 0
        BEGIN
            ROLLBACK
        END
        IF XACT_STATE() = 1 AND @trancount > 0
        BEGIN
            ROLLBACK TRANSACTION NestedProcedure
        END
        RAISERROR ('NestedProcedure: %d: %s', 16, 1, @error, @message)
    END CATCH
END

ALTER PROCEDURE dbo.OuterProcedure
AS
BEGIN
    SET XACT_ABORT OFF
    SET NOCOUNT ON
    BEGIN TRY
        DECLARE @trancount INT
        SET @trancount = @@TRANCOUNT
        IF @trancount = 0
            BEGIN TRANSACTION
        ELSE 
            SAVE TRANSACTION OuterProcedure
            EXEC dbo.NestedProcedure
            SELECT * FROM dbo.Table_2
        IF @trancount = 0
            COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        SELECT XACT_STATE()
        DECLARE @error INT, @message VARCHAR(4000), @xstate INT;
        SELECT @error = ERROR_NUMBER(), @message = ERROR_MESSAGE();
        IF XACT_STATE() = -1
        BEGIN
            ROLLBACK
        END
        IF XACT_STATE() = 1 AND @trancount = 0
        BEGIN
            ROLLBACK
        END
        IF XACT_STATE() = 1 AND @trancount > 0
        BEGIN
            ROLLBACK TRANSACTION OuterProcedure
        END
        RAISERROR ('OuterProcedure: %d: %s', 16, 1, @error, @message)
    END CATCH
END
我把外面的过程叫做

EXEC dbo.OuterProcedure
我得到一个错误,比如

Msg 50000,16级,状态1,程序外程序,第34行
OuterProcedure:50000:NestedProcedure:4922:ALTER TABLE ALTER COLUMN COLUMN 3失败,因为一个或多个对象访问此列

XACT\u STATE()?我只打算将嵌套过程回滚到保存点,不管它是否是运行时错误。有没有办法做到这一点?

XACT_STATE()为-1表示事务是不可模仿的。一旦事务进入这种注定失败的状态,任何类型的写入都不能在事务中提交。某些类别的错误会导致事务进入这种状态。不幸的是,很难清楚地描述是什么样的错误导致了这些错误。请阅读这篇文章,进行深入研究

另外,请参阅TRY..CATCH和XACT_状态文档中的描述

你可能需要考虑更高级别的工作,如果你真的需要你的外部过程来完成一些工作,尽管内部流程注定了事务。一种方法是使用标志重试外部过程,以避免在第一次尝试导致此类错误时重复trasaction dooming错误。

XACT_STATE()为-1表示事务不可模仿。一旦事务进入这种注定失败的状态,任何类型的写入都不能在事务中提交。某些类别的错误会导致事务进入这种状态。不幸的是,很难清楚地描述是什么样的错误导致了这些错误。请阅读这篇文章,进行深入研究

另外,请参阅TRY..CATCH和XACT_状态文档中的描述


你可能需要考虑更高级别的工作,如果你真的需要你的外部过程来完成一些工作,尽管内部流程注定了事务。一种方法是使用标志重试外部过程,以避免在第一次尝试导致此类错误时重复trasaction dooming错误。

谢谢,我将浏览链接。谢谢,我将浏览链接。