メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
トランザクションは、複数の SQL ステートメントを 1 つの作業単位にまとめます。すべてが成功するか、何も起きないかのどちらかです。トランザクションがなければ、複数ステップの操作 — 支払い、送金、注文 — の途中での失敗は、データを壊れた中間状態のまま残しかねません。

基本: BEGIN、COMMIT、ROLLBACK

2 つの更新の間で何かがうまくいかない場合は次のようにします。
ROLLBACK は START TRANSACTION まで戻ってすべてを取り消します。データベースは、トランザクションが始まる前の状態のまま残ります。 BEGIN と START TRANSACTION は同等です。どちらも新しいトランザクションを開始します。

オートコミット

デフォルトでは、MySQL はオートコミットモードで動作します。各ステートメントがそれ自体で 1 つのトランザクションであり、すぐにコミットされます。DELETE FROM orders WHERE id = 5 が明示的な COMMIT なしですぐに反映されるのはそのためです。 START TRANSACTION を呼び出すと、そのトランザクションの間、オートコミットが一時的に停止します。
オートコミットを無効にすると、すべての操作の後に明示的に COMMIT または ROLLBACK する必要があります。コミットせずに切断すると、MySQL は開いているトランザクションをロールバックします。

分離レベル

複数のトランザクションが同時に実行されるとき、分離レベルは、各トランザクションが他のトランザクションから何を見られるかを制御します。MySQL のデフォルトは REPEATABLE READ です。 *InnoDB の REPEATABLE READ はギャップロックによってファントムリードを防止します。これは SQL 標準が要求するより厳格です。 READ COMMITTED は、スループットを優先するアプリケーションでよく選ばれます。ダーティリード(他のトランザクションのコミットされていないデータを見ること)を防止しますが、ノンリピータブルリード(1 つのトランザクションの中で同じ行を 2 回読んだとき、その間に別のトランザクションがコミットしていれば異なる値が返ること)は許可します。

セーブポイント

セーブポイントを使うと、トランザクション全体を放棄せずに、その一部だけをロールバックできます。

トランザクションが対象としないもの

すべての MySQL ステートメントがロールバックできるわけではありません。DDL ステートメント(CREATE TABLE、ALTER TABLE、DROP TABLE)は暗黙のコミットを引き起こします。MySQL はそれらを実行する前に開いているトランザクションをコミットし、DDL 自体はロールバックできません。

よくある質問

トランザクションが一度もコミットされないとどうなりますか?

コミットせずに接続を閉じると、MySQL は開いているトランザクションを自動的にロールバックします。サーバーがクラッシュした場合、InnoDB の redo ログが起動時にコミット済みのトランザクションを回復し、コミットされていないものをロールバックします。

MyISAM でトランザクションを使えますか?

いいえ。トランザクションにはトランザクション対応のストレージエンジンが必要です。InnoDB(MySQL のデフォルトエンジン)はトランザクションを完全にサポートします。MyISAM はサポートしません。MyISAM テーブルに対するステートメントはすぐに反映され、ロールバックできません。

トランザクションはどのくらいの時間開いたままにできますか?

技術的には必要なだけ開いておけますが、長時間実行されるトランザクションはロックを保持し、undo ログの領域を消費するので、他のトランザクションにパフォーマンスの問題を引き起こします。innodb_lock_wait_timeout 変数(デフォルト: 50 秒)は、トランザクションがエラーを返す前にロックをどのくらい待つかを制御します。トランザクションは短く保ち、作業が終わったらすぐにコミットしてください。

トラブルシューティング

関連項目