はじめに
トランザクション分離レベルとは2つ以上のトランザクションの間同士でのお互いの操作の影響度合いを定義したものです。
具体的にトランザクション分離レベルが何なのかを理解するためには、リード現象(Read phenomena)である「ダーティリード(Dirty reads)」「ノンリピータブルリード(Non-repeatable reads)」「ファントムリード(Phantom reads)」の3種類の違いを理解する必要があります。
本記事ではこの3種のリード現象を例を用いて解説し、トランザクション分離レベルの定義を記載しています。
3種のリード現象
説明に利用する例
以下のArticles
(記事)テーブルという擬似的なテーブルを例に進めます。
Id | Title | Tag |
---|---|---|
1 | Let's start using Docker! | Container |
2 | Why should you learn Go? | Go |
ダーティリード(Dirty reads)
Flow | トランザクション1(T1) | トランザクション2(T2) | 説明 |
---|---|---|---|
Step1 | SELECT Tag FROM Articles WHERE Id = 1; | T1は"Container"でReadする | |
Step2 | UPDATE Articles SET Tag = 'Docker' WHERE id = 1; | T2はCommitしない | |
Step3 | SELECT Tag FROM Articles WHERE Id = 1; | T1は"Docker"でReadされる(ダーティリード現象) | |
Step4 | ROLLBACK; | T2はロールバック可能 |
上記のようにダーティリードは、COMMITされていないトランザクションでの変更を他トランザクションがReadすることができてしまう現象のことを指します。
ノンリピータブルリード(Non-repeatable reads)
Flow | トランザクション1(T1) | トランザクション2(T2) | 説明 |
---|---|---|---|
Step1 | SELECT * FROM Articles; | T1は全2レコードをクエリする | |
Step2 | UPDATE Articles SET Tag = 'Docker' WHERE id = 1; | ここではT1は対象レコードを読み取れない | |
Step3 | COMMIT; | T2がコミットされる | |
Step4 | SELECT Tag FROM Articles WHERE Id = 1; | T1は"Docker"でReadされる(ノンリピータブルリード現象) |
上記のようにノンリピータブルリードは、他トランザクション(T2)がコミットにより対象レコードを更新した場合、1トランザクション(T1)中でReadするレコードデータが異なってしまう現象を指します。
ファントムリード(Phantom reads)
Flow | トランザクション1(T1) | トランザクション2(T2) | 説明 |
---|---|---|---|
Step1 | SELECT * FROM Articles; | T1は全2レコードをクエリする | |
Step2 | INSERT INTO Articles(Id,Title,Tag) VALUES (3, 'How to start Go', 'Go'); | T2で新規レコードを追加する | |
Step3 | COMMIT; | T2がコミットされる | |
Step4 | SELECT * FROM Articles; | T1は全3レコードをクエリする(ファントムリード現象) |
上記のようにファントムリードは、他トランザクション(T2)がコミットにより新規レコード追加(または削除)をした場合、1トランザクション(T1)中でReadするテーブルデータが異なってしまう現象を指します。
トランザクション分離レベル VS リード現象 対応表
上記のリード現象と代表的なトランザクション分離レベルとの対応表は下記テーブルのようになります。
X: 発生し得る(may occur)
O: 発生しない(don't occur)
トランザクション分離レベル | Dirty reads | Non-repeatable reads | Phantoms reads |
---|---|---|---|
Read Uncommitted | X | X | X |
Read Committed | O | X | X |
Repeatable Read | O | O | X |
Serializable | O | O | O |
トランザクション分離レベルのより細かい種類と、各種リード現象をどのよう防ぐかの設計・実装は、PostgreSQL、MySQL、SQLSeverなど各RDBMSにより異なります。設定の際はそれぞれの公式ドキュメントを参照する必要があります。