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 WRITE
とREAD 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
システム変数の説明を参照してください。
BEGIN
と BEGIN 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
句と同様に、COMMIT
と ROLLBACK
に対してサポートされています。 CHAIN
と RELEASE
は、トランザクションの完了に対する追加の制御に使用できます。 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 では、BEGIN
、COMMIT
、および ROLLBACK
は --replicate-do-db
または --replicate-ignore-db
ルールによって影響を受けません。
InnoDB
でトランザクションの完全なロールバックが実行されると、トランザクションで設定されたすべてのロックが解放されます。 重複キーエラーなどのエラーの結果としてトランザクション内の単一の SQL ステートメントがロールバックされた場合、そのステートメントによって設定されたロックは、トランザクションがアクティブなまま保持されます。 これが発生する原因は、InnoDB
では、どの行がどのステートメントで設定されたのかをあとで確認できないような形式で、行ロックが格納されるためです。
トランザクション内の SELECT
ステートメントがストアドファンクションをコールし、ストアドファンクション内のステートメントが失敗した場合、そのステートメントはロールバックされます。 その後、ROLLBACK
がトランザクションに対して実行されると、トランザクション全体がロールバックされます。