トランザクションとは
データベースの、一連の処理をひとまとめにしたものをトランザクションと呼びます。
ACID特性とは
データベーストランザクションの信頼性と整合性を保証するための4つの特性が必須とされます。
それぞれ以下の頭文字を取ってACID特性と呼ばれます。
Atomicity (原子性)
トランザクションの処理結果は「すべて実行されるか」「全く実行されないか」のいずれかであること。
中途半端に処理が終わることは許容しません。
Consistency (一貫性)
トランザクション前後で、データベースの内容が矛盾ない状態であること。
Isolation (隔離性・分離性)
複数のトランザクションを同時に実行した場合と、順番に実行した場合の処理結果が一致すること。つまり、それぞれのトランザクションがお互いに影響を受けず排他的に処理することです。
Durability (耐久性)
正常に終了したトランザクションの更新結果は、永続的に保存されること。つまり、例えシステム障害が発生しても、データベースから消失しないことです。
トランザクション分離レベル
トランザクション分離レベル(Transaction Isolation Level)とは、ACID属性のうち、**Isolation (隔離性) **を調整するための指標です。
データベースで複数のトランザクションが実行されるとき、「データの一貫性をどれだけ厳密に保つか」 を定義した設定を指します。
理想を言えば、すべての処理を完全に1つずつ順番に実行すればデータは正確になりますが、それだと処理まちが発生してパフォーマンスが悪化してしまいます。
そこで「パフォーマンス」と「データの正確さ」を調整できるように、4つのレベルが定義されています。
分離レベルはそれぞれ以下があります。
| 分離レベル | 読み取りの整合性 | 発生しうる現象 | 処理速度 |
|---|---|---|---|
| ① READ UNCOMMITTED | 最低 | ダーティリード、ファジーリード、ファントムリード | 最速 |
| ② READ COMMITTED | 低 | ファジーリード、ファントムリード | 高速 |
| ③ REPEATABLE READ | 高(※MySQLのデフォルト) | ファントムリード | やや遅い |
| ④ SERIALIZABLE | 最高 | なし | 最も遅い |
分離レベルが低いと発生しうる現象
1. ダーティリード(Dirty Read)
他のトランザクションがまだ確定(コミット)していない、書き換え途中のデータを読み込んでしまう現象。
その処理が後からキャンセル(ロールバック)された場合、存在しないデータを元に処理を進めてしまうことになります。
例)
トランザクション①(振込処理) → 口座残高を10000円から5000円に引く → エラーが発生したため処理をキャンセル → 口座残高が10000円に戻る
トランザクション②(残高照会) → ↑の5000円を読み取る → 5000円と表示される!
2. ファジーリード(Fuzzy Read / Non-repeatable Read)
同じトランザクション内で同じデータを2回読み込んだ時、1回目と2回目で値が変わってしまう現象。自分が読み込んでいる間に、他のトランザクションがデータを更新してコミットしてしまうため起こります。
例)
トランザクション①(在庫チェック) → 1回目の在庫確認「10個」 → → 2回目の在庫確認「9個」
トランザクション②(購入処理) → → 在庫を「9個」に減らしてコミット
3. ファントムリード(Phantom Read)
同じトランザクション内で同じ条件の範囲検索を2回行った時、2回目には1回目に存在しなかった「幻のデータ」が出現(または消失)する現象。自分が処理している最中に、他のトランザクションが新しいレコードを追加・削除してコミットするために起こります。
例)
トランザクション①(メルマガ送信) → 東京の会員を検索 →「2人」 → → 東京の会員を再検索 ➔ 「3人」
トランザクション②(新規会員登録) → → 東京の会員を追加
まとめ
業務で「REPEATABLE READ」という単語が出てきたので、調べてみたら奥が深かったです。今後の技術選定の参考にしたいと思います。