次の方法で共有


XACT_STATE (Transact-SQL)

現在実行されている要求のユーザー トランザクション状態を報告するスカラ関数です。XACT_STATE は、要求にアクティブなユーザー トランザクションがあるかどうか、およびそのトランザクションがコミット可能かどうかを示します。

トピック リンク アイコンTransact-SQL 構文表記規則

構文

XACT_STATE()

戻り値の型

smallint

説明

XACT_STATE では次の値が返されます。

戻り値

意味

1

現在の要求にアクティブなユーザー トランザクションが存在する。要求では、データ書き込み、トランザクションのコミットなど、任意の操作を実行できます。

0

現在の要求にアクティブなユーザー トランザクションが存在しない。

-1

現在の要求にアクティブなユーザー トランザクションが存在するが、コミットできないトランザクションとして分類されるエラーが発生した。この場合、要求でトランザクションのコミットまたはセーブポイントへのロールバックは行えず、トランザクションの完全ロールバックだけを要求できます。要求では、トランザクションをロールバックするまで書き込み操作は実行できず、読み取り操作だけを実行できます。トランザクションがロールバックされた後は、要求では読み取り、書き込み両方の操作を実行でき、新しいトランザクションを開始できます。

バッチの実行が完了すると、コミット不可能なトランザクションは、データベース エンジンによって自動的にロールバックされます。トランザクションがコミット不可能な状態になったときにエラー メッセージが送信されなかった場合、バッチが完了すると、エラー メッセージがクライアント アプリケーションに送信されます。このメッセージは、コミット不可能なトランザクションが検出され、ロールバックされたことを示します。コミットできないトランザクションの詳細については、「Transact-SQL での TRY...CATCH の使用」を参照してください。

現在の要求にアクティブなユーザー トランザクションがあるかどうかを検出するには、XACT_STATE 関数と @@TRANCOUNT 関数の両方を使用できます。ただし、@@TRANCOUNT では、検出されたトランザクションがコミット不可能なトランザクションとして分類されているかどうかは判断できません。また、XACT_STATE では、入れ子になったトランザクションが存在するかどうかは判断できません。

次の例では、TRY...CATCH 構造の CATCH ブロックで XACT_STATE を使用し、トランザクションをコミットまたはロールバックするかどうかを確認します。ここでは SET XACT_ABORT が ON に設定されているため、制約違反エラーによってトランザクションはコミットできない状態になります。

USE AdventureWorks;
GO

-- SET XACT_ABORT ON will render the transaction uncommittable
-- when the constraint violation occurs.
SET XACT_ABORT ON;

BEGIN TRY
    BEGIN TRANSACTION;
        -- A FOREIGN KEY constraint exists on this table. This 
        -- statement will generate a constraint violation error.
        DELETE FROM Production.Product
            WHERE ProductID = 980;

    -- If the delete operation succeeds, commit the transaction. The CATCH
    -- block will not execute.
    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    -- Test XACT_STATE for 0, 1, or -1.
    -- If 1, the transaction is committable.
    -- If -1, the transaction is uncommittable and should 
    --     be rolled back.
    -- XACT_STATE = 0 means there is no transaction and
    --     a commit or rollback operation would generate an error.

    -- Test whether the transaction is uncommittable.
    IF (XACT_STATE()) = -1
    BEGIN
        PRINT 'The transaction is in an uncommittable state.' +
              ' Rolling back transaction.'
        ROLLBACK TRANSACTION;
    END;

    -- Test whether the transaction is active and valid.
    IF (XACT_STATE()) = 1
    BEGIN
        PRINT 'The transaction is committable.' + 
              ' Committing transaction.'
        COMMIT TRANSACTION;   
    END;
END CATCH;
GO