MySQL 8.0 リファレンスマニュアル MySQL NDB Cluster 8.0 を含む

このページは機械翻訳したものです。

13.3.1 START TRANSACTION、COMMIT および ROLLBACK ステートメント

START TRANSACTION
    [transaction_characteristic [, transaction_characteristic] ...]

transaction_characteristic: {
    WITH CONSISTENT SNAPSHOT
  | READ WRITE
  | READ ONLY
}

BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET autocommit = {0 | 1}

次のステートメントにより、トランザクションの使用を制御できます。

デフォルトでは、MySQL は自動コミットモードが有効になった状態で動作します。 つまり、特にトランザクション内にない場合、各ステートメントは START TRANSACTION および COMMIT で囲まれているかのようにアトミックです。 ROLLBACK を使用して効果を元に戻すことはできませんが、ステートメントの実行中にエラーが発生した場合、ステートメントはロールバックされます。

一連のステートメントに対して自動コミットモードを暗黙的に無効にするには、START TRANSACTION ステートメントを使用します。

START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;

START TRANSACTION を使用すると、そのトランザクションを COMMIT または ROLLBACK で終了するまで、自動コミットは無効のままになります。 そのあと、自動コミットモードはその以前の状態に戻ります。

START TRANSACTION では、トランザクションの特性を制御するいくつかの修飾子が許可されます。 複数の修飾子を指定するには、それらをカンマで区切ります。

重要

MySQL クライアントアプリケーションを記述するために使用される多くの API (JDBC など) は、クライアントから START TRANSACTION ステートメントを送信する代わりに使用できる (また、場合によっては使用すべき)、トランザクションを開始するための独自のメソッドを提供しています。 詳細は、第29章「Connector および APIまたは API のドキュメントを参照してください。

自動コミットモードを明示的に無効にするには、次のステートメントを使用します。

SET autocommit=0;

autocommit 変数を 0 に設定することによって自動コミットモードを無効にしたあと、トランザクションセーフテーブル (InnoDB または NDB のテーブルなど) への変更がただちに永続的になることはありません。 COMMIT を使用して変更をディスクに格納するか、または ROLLBACK を使用して変更を無視する必要があります。

autocommit はセッション変数であるため、セッションごとに設定する必要があります。 新しい接続ごとに自動コミットモードを無効にするには、セクション5.1.8「サーバーシステム変数」にある autocommit システム変数の説明を参照してください。

BEGINBEGIN WORK は、トランザクションを開始するための START TRANSACTION のエイリアスとしてサポートされています。 標準の SQL 構文である START TRANSACTION は、アドホックトランザクションを開始するための推奨される方法であり、BEGIN では許可されない修飾子が許可されます。

BEGIN ステートメントは、BEGIN ... END 複合ステートメントを開始する BEGIN キーワードの使用とは異なります。 後者はトランザクションを開始しません。 セクション13.6.1「BEGIN ... END 複合ステートメント」を参照してください。

注記

すべてのストアドプログラム (ストアドプロシージャーとストアドファンクション、トリガー、およびイベント) 内で、パーサーは、BEGIN [WORK]BEGIN ... END ブロックの開始として扱います。 このコンテキストでは、代わりに START TRANSACTION を使用してトランザクションを開始します。

オプションの WORK キーワードは、CHAIN および RELEASE 句と同様に、COMMITROLLBACK に対してサポートされています。 CHAINRELEASE は、トランザクションの完了に対する追加の制御に使用できます。 completion_type システム変数の値によって、デフォルトの完了動作が決定されます。 セクション5.1.8「サーバーシステム変数」を参照してください。

AND CHAIN 句を指定すると、現在のトランザクションが終了するとすぐに新しいトランザクションが開始され、新しいトランザクションの分離レベルは終了したばかりのトランザクションと同じになります。 新しいトランザクションでは、終了理由トランザクションと同じアクセスモード (READ WRITE または READ ONLY) も使用されます。 RELEASE 句を指定すると、サーバーは、現在のトランザクションを終了したあと現在のクライアントセッションを切り離します。 NO キーワードを含めると、CHAIN または RELEASE の完了が抑制されます。これは、completion_type システム変数がデフォルトで、チェーンまたはリリースの完了が実行されるように設定されている場合に役立つことがあります。

トランザクションを開始すると、保留中のトランザクションはすべてコミットされます。 詳細は、セクション13.3.3「暗黙的なコミットを発生させるステートメント」を参照してください。

また、トランザクションを開始すると、ユーザーが UNLOCK TABLES を実行したかのように、LOCK TABLES によって取得されたテーブルロックも解放されます。 トランザクションを開始しても、FLUSH TABLES WITH READ LOCK によって取得されたグローバルな読み取りロックは解放されません。

最適な結果を得るために、トランザクションは、1 つのトランザクションセーフストレージエンジンによって管理されているテーブルのみを使用して実行するようにしてください。 そうしないと、次の問題が発生する場合があります。

各トランザクションは、COMMIT 時に、1 つのまとまりでバイナリログに格納されます。 ロールバックされたトランザクションはログに記録されません。 (例外: 非トランザクションテーブルへの変更はロールバックできません。 ロールバックされるトランザクションに非トランザクションテーブルへの変更が含まれている場合は、非トランザクションテーブルへの変更が確実にレプリケートされるようにするために、最後に ROLLBACK ステートメントを使用してトランザクション全体がログに記録されます。) セクション5.4.4「バイナリログ」を参照してください。

トランザクションの分離レベルまたはアクセスモードは、SET TRANSACTION ステートメントを使用して変更できます。 セクション13.3.7「SET TRANSACTION ステートメント」を参照してください。

ロールバックは、ユーザーが明示的に求めることなく (たとえば、エラーの発生時に) 暗黙的に発生する可能性のある低速な操作になる場合があります。 このため、ROLLBACK ステートメントを使用して実行された明示的なロールバックに対してだけでなく、暗黙のロールバックに対しても、SHOW PROCESSLIST はセッションの State カラムに Rolling back を表示します。

注記

MySQL 8.0 では、BEGINCOMMIT、および ROLLBACK--replicate-do-db または --replicate-ignore-db ルールによって影響を受けません。

InnoDB でトランザクションの完全なロールバックが実行されると、トランザクションで設定されたすべてのロックが解放されます。 重複キーエラーなどのエラーの結果としてトランザクション内の単一の SQL ステートメントがロールバックされた場合、そのステートメントによって設定されたロックは、トランザクションがアクティブなまま保持されます。 これが発生する原因は、InnoDB では、どの行がどのステートメントで設定されたのかをあとで確認できないような形式で、行ロックが格納されるためです。

トランザクション内の SELECT ステートメントがストアドファンクションをコールし、ストアドファンクション内のステートメントが失敗した場合、そのステートメントはロールバックされます。 その後、ROLLBACK がトランザクションに対して実行されると、トランザクション全体がロールバックされます。