トランザクションの制御 (データベース エンジン)

アプリケーションは、主にトランザクションの開始タイミングと終了タイミングを指定してトランザクションを制御します。これについては、Transact-SQL ステートメントまたはデータベース アプリケーション プログラミング インターフェイス (API) 関数のいずれかを使用して指定できます。また、トランザクションが完了せずに終了した場合、その原因となったエラーがシステムによって正しく処理される必要があります。

既定では、トランザクションは接続レベルで管理されます。接続時にトランザクションが開始すると、その接続で実行されるすべての Transact-SQL ステートメントが、トランザクションが終了するまでそのトランザクションの一部になります。ただし、複数のアクティブな結果セット (MARS) セッションでは、Transact-SQL の明示的または暗黙的なトランザクションは、バッチ レベルで管理されるバッチスコープのトランザクションになります。バッチの完了時にバッチスコープのトランザクションがコミットまたはロールバックされていない場合、SQL Server により、トランザクションは自動的にロールバックされます。

トランザクションの開始

SQL Server データベース エンジンのインスタンスでは、API 関数や Transact-SQL ステートメントを使用して、明示的、自動コミット、または暗黙のいずれかのトランザクションとしてトランザクションを開始できます。MARS セッションでは、Transact-SQL の明示的および暗黙のトランザクションはバッチスコープのトランザクションになります。

  • 明示的なトランザクション
    API 関数または Transact-SQL の BEGIN TRANSACTION ステートメントを使用して、トランザクションを明示的に開始します。

  • トランザクションの自動コミット
    データベース エンジンの既定のモードです。各 Transact-SQL ステートメントは、完了時にコミットされます。トランザクションを制御するためにステートメントを指定する必要はありません。

  • 暗黙のトランザクション
    暗黙のトランザクション モードは、API 関数または Transact-SQL SET IMPLICIT_TRANSACTIONS ON ステートメントのいずれかを使用して設定します。その次のステートメントによって、新しいトランザクションが自動的に開始されます。そのトランザクションが完了すると、その次の Transact-SQL ステートメントによって新しいトランザクションが開始されます。

  • バッチスコープのトランザクション
    (複数のアクティブな結果セット (MARS) の場合のみ) MARS セッションで開始された Transact-SQL の明示的または暗黙的なトランザクションは、バッチスコープのトランザクションになります。バッチの完了時にコミットまたはロールバックされていないバッチスコープのトランザクションは、SQL Server により自動的にロールバックされます。

トランザクション モードは接続レベルで管理されます。ある接続のトランザクション モードを変更しても、その他の接続のトランザクション モードには影響しません。

トランザクションの終了

トランザクションは、COMMIT ステートメント、ROLLBACK ステートメント、または API 関数を使用して終了できます。

  • COMMIT
    トランザクションが正常に完了した場合、そのトランザクションをコミットします。COMMIT ステートメントは、トランザクションのすべての変更をデータベースの一部として組み込みます。また、COMMIT により、トランザクションで使用されていたロックなどのリソースが解放されます。

  • ROLLBACK
    トランザクションでエラーが発生した場合やユーザーがトランザクションをキャンセルする場合は、トランザクションをロールバックします。ROLLBACK ステートメントは、データをトランザクションの開始時点の状態に戻すことにより、トランザクションで行われた変更をすべて元に戻します。また、ROLLBACK により、トランザクションで保持されていたリソースが解放されます。

注意注意

複数のアクティブな結果セット (MARS) をサポートできる接続では、保留中の実行要求がある間は、API 関数を使用して開始された明示的なトランザクションをコミットできません。実行中の未処理の操作があるときに、このようなトランザクションをコミットしようとするとエラーが発生します。

トランザクションの境界の指定

Transact-SQL ステートメントまたは API の関数やメソッドを使用して、データベース エンジン トランザクションを開始および終了する時点を特定できます。

  • Transact-SQL ステートメント
    トランザクションを記述するには、BEGIN TRANSACTION、COMMIT TRANSACTION、COMMIT WORK、ROLLBACK TRANSACTION、ROLLBACK WORK、および SET IMPLICIT_TRANSACTIONS の各ステートメントを使用します。これらのステートメントは、主に DB-Library アプリケーションと Transact-SQL スクリプト (osql コマンド プロンプト ユーティリティを使用して実行されるスクリプトなど) で使用されます。

  • API の関数およびメソッド
    データベース API (ODBC、OLE DB、ADO、.NET Framework SQLClient 名前空間など) には、トランザクションを記述するための関数またはメソッドが含まれています。これらの関数またはメソッドは、データベース エンジン アプリケーションでトランザクションを制御するために使用する主要なメカニズムです。

各トランザクションは上記のいずれかの方法で管理する必要があります。1 つのトランザクションで両方の方法を使用すると、未定義の結果が生じることがあります。たとえば、ODBC の API 関数を使用してトランザクションを開始してから、Transact-SQL の COMMIT ステートメントを使用してトランザクションを完了しないでください。この方法では、SQL Server の ODBC ドライバにトランザクションがコミットされたことが通知されません。この場合、ODBC の SQLEndTran 関数を使用してトランザクションを終了します。

トランザクション処理中のエラー

エラーによりトランザクションを正常に完了できない場合、SQL Server によってトランザクションが自動的にロールバックされ、そのトランザクションで保持されていたすべてのリソースが解放されます。データベース エンジンのインスタンスへのクライアントのネットワーク接続が切断された場合、ネットワークからインスタンスにこの切断が通知されると、その接続に対する未処理のトランザクションがすべてロールバックされます。クライアント アプリケーションが失敗した場合、またはクライアント コンピュータがダウンするか再起動される場合も、接続が切断されます。データベース エンジンのインスタンスでは、ネットワークからこの切断が通知されると、未処理の接続がすべてロールバックされます。クライアントがアプリケーションからログオフした場合、未処理のトランザクションはすべてロールバックされます。

バッチでランタイム ステートメント エラー (制約違反など) が発生した場合、データベース エンジンの既定の動作として、エラーの原因となったステートメントだけがロールバックされます。この動作を変更するには、SET XACT_ABORT ステートメントを使用します。SET XACT_ABORT ON の実行後、任意のランタイム ステートメント エラーにより、現在のトランザクションが自動的にロールバックされます。構文エラーなどのコンパイル エラーは、SET XACT_ABORT の設定の影響を受けません。詳細については、「SET XACT_ABORT (Transact-SQL)」を参照してください。

エラーが発生した場合は、修正措置 (COMMIT または ROLLBACK) をアプリケーション コードに含める必要があります。トランザクションで発生するエラーなど、エラーを処理するための効果的なツールには Transact-SQL TRY…CATCH 構造があります。トランザクションを含む例の詳細については、「Transact-SQL での TRY...CATCH の使用」および「TRY...CATCH (Transact-SQL)」を参照してください。