この記事では、mysql トランザクション分離の実装について説明します。
分離と分離レベル
| 未コミットの読み取り | トランザクションがコミットする前に行った変更は、他のトランザクションから見ることができます。 |
| コミット済み読み取り | トランザクションがコミットした後にのみ、トランザクションが行った変更を他のトランザクションが見ることができます。 |
| 繰り返し可能 | トランザクションの実行中に見られるデータは、トランザクションの開始時に見られるデータと常に同じです。再読可能な分離レベルでは、コミットされていない変更も他のトランザクションからは見えません。 |
| シリアライズ | ロックは同じ行のレコードに対して適用されます。後からアクセスするトランザクションは、前のトランザクションが完了するのを待ってから実行を続けなければなりません。 |
概念だけではつまらないとわかっていても、雲をつかむような話になってしまいがちです。そこで、上記の4つの分離レベルの違いを説明するために簡単な例を挙げます。データテーブルTに列が1つしかなく、行の1つに値1があるとします。
mysql> create table T(c int) engine=InnoDB;
insert into T(c) values(1);
以下の2つのトランザクションが時系列順に実行されます:
- Read Uncommitted トランザクションBは値を2に変更します。V1の値はコミットされていない値が読み取られたため2です。
- コミットされた読み取り トランザクションBからの更新はコミットされた後でないと確認できないため、V1の値は1、V2とV3の値は両方とも2です。
- トランザクションの実行中に見られるデータは、その前後で同じでなければならないからです。
- V1とV2の値は1、V3の値は2です。なぜなら、トランザクションAはクエリ時にロックを取得し、トランザクションBはトランザクションAが完了するまでロックされ、 できないからです。
トランザクション分離の実装原理
実装では、データベース内部にビューが作成され、アクセス時にはビューの論理結果が優先されます。
| コミットされない読み取り | ビューの概念はなく、レコードの最新値を直接返します。 |
| コミット済み読み取り | 各SQL文の実行開始時 |
| 繰り返し可能 | トランザクション開始時 |
| 直列化 | ロックで直接並列アクセスを回避 |
トランザクション開始メソッド
- 自動コミットをオフにする autocommit=0 を設定すると、自動コミット・トランザクションがオフになり、コミットまたはロールバック文が積極的に実行されます。



