Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


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

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}

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

  • START TRANSACTION または BEGIN は、新しいトランザクションを開始します。

  • COMMIT は、現在のトランザクションをコミットして、その変更を永続的なものにします。

  • ROLLBACK は、現在のトランザクションをロールバックして、その変更を取り消します。

  • SET autocommit は、現在のセッションのデフォルトの自動コミットモードを無効または有効にします。

デフォルトでは、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 では、トランザクションの特性を制御するいくつかの修飾子が許可されます。 複数の修飾子を指定するには、それらをカンマで区切ります。

  • WITH CONSISTENT SNAPSHOT 修飾子は、この機能に対応しているストレージエンジンでの一貫性読み取りを開始します。 これは、InnoDB にのみ適用されます。 その効果は、任意の InnoDB テーブルから START TRANSACTION に続けて SELECT を発行することと同じです。 セクション15.7.2.3「一貫性非ロック読み取り」を参照してください。 WITH CONSISTENT SNAPSHOT 修飾子は、現在のトランザクション分離レベルを変更しないため、現在の分離レベルが一貫性読み取りを許可するものである場合にのみ、整合性のあるスナップショットを提供します。 一貫性読み取りを許可する分離レベルは、REPEATABLE READ だけです。 その他のすべての分離レベルの場合、WITH CONSISTENT SNAPSHOT 句は無視されます。 WITH CONSISTENT SNAPSHOT 句が無視されると、警告が生成されます。

  • READ WRITE および READ ONLY 修飾子は、トランザクションアクセスモードを設定します。 これらは、そのトランザクションで使用されるテーブルへの変更を許可または禁止します。 READ ONLY の制限は、そのトランザクションが、ほかのトランザクションに表示されるトランザクションテーブルと非トランザクションテーブルの両方を変更またはロックしないようにします。このトランザクションは引き続き、一時テーブルを変更またはロックできます。

    MySQL では、トランザクションが読み取り専用であることがわかっている場合、InnoDB テーブルに対するクエリーの追加の最適化が可能です。 READ ONLY を指定すると、読み取り専用ステータスを自動的に特定できない場合に、これらの最適化が適用されることが保証されます。 詳細は、セクション8.5.3「InnoDB の読み取り専用トランザクションの最適化」を参照してください。

    アクセスモードが指定されていない場合は、デフォルトモードが適用されます。 デフォルトが変更されていないかぎり、それは読み取り/書き込みです。 同じステートメント内で READ WRITEREAD ONLY の両方を指定することは許可されません。

    読み取り専用モードでは、DML ステートメントを使用して TEMPORARY キーワードで作成されたテーブルは引き続き変更できます。 永続的なテーブルと同様に、DDL ステートメントによって行われる変更は許可されません。

    トランザクションアクセスモードの詳細 (デフォルトモードを変更する方法を含む) は、セクション13.3.7「SET TRANSACTION ステートメント」を参照してください。

    read_only システム変数が有効になっている場合、START TRANSACTION READ WRITE でトランザクションを明示的に開始するには、CONNECTION_ADMIN 権限 (または非推奨の SUPER 権限) が必要です。

重要

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 つのトランザクションセーフストレージエンジンによって管理されているテーブルのみを使用して実行するようにしてください。 そうしないと、次の問題が発生する場合があります。

  • 複数のトランザクションセーフストレージエンジン (InnoDB など) のテーブルを使用し、トランザクション分離レベルが SERIALIZABLE でない場合、あるトランザクションがコミットされると、同じテーブルを使用する別の進行中のトランザクションには、最初のトランザクションによって行われた変更の一部のみが表示される可能性があります。 つまり、混在したエンジンではトランザクションのアトミック性が保証されないため、不整合が発生する場合があります。 (混在したエンジンでのトランザクションの頻度が低い場合は、SET TRANSACTION ISOLATION LEVEL を使用して、必要に応じてトランザクションごとに分離レベルを SERIALIZABLE に設定できます。)

  • トランザクション内でトランザクションセーフでないテーブルを使用する場合は、自動コミットモードのステータスには関係なく、それらのテーブルへの変更が一度に格納されます。

  • トランザクション内で非トランザクションテーブルを更新したあとに ROLLBACK ステートメントを発行すると、ER_WARNING_NOT_COMPLETE_ROLLBACK 警告が発生します。 トランザクションセーフテーブルへの変更はロールバックされますが、非トランザクションセーフテーブルへの変更はロールバックされません。

各トランザクションは、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 がトランザクションに対して実行されると、トランザクション全体がロールバックされます。