当前事务无法提交,也无法回滚到保存点。回滚整个事务 - 'Msg 3931,Level 16,State 1

Ard*_*oli 5 sql t-sql transactions sql-server-2014

我使用 SQL Server 2014 并且我已经运行了这个测试 T/SQL。

    BEGIN TRY
        BEGIN TRANSACTION T1

        CREATE TABLE aa9
        (
            A int
        )

        SAVE TRANSACTION S1

        INSERT INTO aa9 (A) VALUES ('aa')

        COMMIT TRANSACTION T1

    END TRY 
    BEGIN CATCH 
        ROLLBACK TRANSACTION S1
        PRINT 'Error ..... '
        ;throw
    END CATCH 
Run Code Online (Sandbox Code Playgroud)

为什么我会收到此错误:

消息 3931,级别 16,状态 1,第 17 行
当前事务无法提交,也无法回滚到保存点。回滚整个事务。

我应该能够将事务回滚到我的 SavePoint 事务吗?

小智 0

如果您的 XACT_State() 不是 -1,您实际上只能回滚保存事务。这实际上并不适用于插入语句,因为即使您回滚保存点,这也会破坏所有事务的 XACT_State()。因此,您可以将它用于除以零和转换错误之类的事情,但 SQL Server 并不像您希望的那么复杂。

但是,只要添加一堆检查,您就可以获得某种形式的嵌套事务,如下所示。

MSDN 的强制链接:https://learn.microsoft.com/en-us/sql/t-sql/functions/xact-state-transact-sql ?view=sql-server-ver16

DROP TABLE IF EXISTS aa9;
BEGIN TRANSACTION T2;
BEGIN TRY
    CREATE TABLE aa9
    (
        A int
    )
    PRINT 'Starting T2'

    SAVE TRANSACTION T2;
    INSERT INTO aa9(A) VAlUES (1);
    PRINT 'Starting T3'
    BEGIN TRANSACTION T3
    SAVE TRANSACTION T3
    BEGIN TRY
        INSERT INTO aa9 (A) VALUES (2)
        PRINT 'Forcing Error that doesn''t blow XACT_STATE()'
        SELECT 1/0 --Comment This Line  To See Difference
        INSERT INTO aa9(A) VALUES ('A')
        PRINT 'Committing T3'
        COMMIT TRANSACTION T3
    END TRY
    BEGIN CATCH
            PRINT 'Rolling Back T3'
            ROLLBACK TRANSACTION T3;
            THROW
    END CATCH
    COMMIT TRANSACTION T2;
END TRY 
BEGIN CATCH 
    IF XACT_STATE() = -1
    BEGIN
    ROLLBACK TRANSACTION
    PRINT 'Error ..... '
    END
    ELSE
    BEGIN
     COMMIT TRANSACTION T2;
     PRINT 'Preserving T2..... '

    END;
    throw
END CATCH 
GO
SELECT * FROM aa9
Run Code Online (Sandbox Code Playgroud)