VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
基本: BEGIN、COMMIT、ROLLBACK
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 秒)は、トランザクションがエラーを返す前にロックをどのくらい待つかを制御します。トランザクションは短く保ち、作業が終わったらすぐにコミットしてください。
トラブルシューティング
関連項目
- MySQL の外部キー — 外部キーのチェックはトランザクションの作業の一部
- MySQL のデッドロック — 2 つのトランザクションが互いをロックし合うと何が起きるか
- MySQL の UPSERT — トランザクション内での INSERT … ON DUPLICATE KEY UPDATE
- MySQL での一括挿入 — 速度のために書き込みをトランザクションにまとめる
- MySQL の COMMIT と ROLLBACK — 実例付きの START TRANSACTION、COMMIT、ROLLBACK