TRANSACTION ISOLATION LEVELとは
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
まとめ
TRANSACTION ISOLATION LEVELとは、1トランザクション内において選択されたレコード もしくはレコード(キー)範囲が、 その他のトランザクションのレコード操作からどれだけ分離(隔離) されるかについて、その段階を定義したものです。
TRANSACTION ISOLATION LEVELには、以下の4種類が定義されています
下のものほど高い分離性を持っていますが、データベースへの負荷や同時実行性能やパフォーマンスに与える影響が大きくなります。
COMMITされていない内容の読み込み(ダーティリード)を許容するレベルです。レコードのロックやら何やらは行わないので、DBへの負荷は一番少ないと言えます。
ダーティリードを防止(COMMITされた内容のみを取得)するレベルです。
選択したレコード、キー範囲に対するロック、もしくは何らかの領域へのデータ退避は行われないので、複数回の読み取りにおいてはレコードの件数や内容に差異が生じる可能性があります。
ダーティリードを防止する他に、レコード再読み取り時に、再読み取りされたレコードが他のトランザクションからの影響されないことを保障するレベルです。
つまり、再読み取り前に更新などが行われレコード内容が変わってしまうことを防ぎます。
もちろん自トランザクションからの更新内容は反映されます。
再読み取りを可能とするために、選択されたレコードは、他トランザクションからの削除、更新操作から保護されます。
ただし、あくまで、選択されたレコードに対する保護であって、選択されたキー範囲への保護ではないため、他トランザクションが選択キー範囲内にレコードを追加することは可能です。
つまり、1トランザクション内で、レコードの再読み取りが行われるたびに、前回の読み取り時には存在しなかったレコードが現れる可能性が存在します。
このようなレコードは、ファントムレコードと呼ばれています。
選択レコード範囲を、他トランザクションの影響から完全に分離するレベルです。
このレベルはCOMMITされたレコードのみを読み取り、再読み取りを可能とし、ファントムレコードも防止します。
ですが、そのような操作はロック等を多用して実現されることとなりますので、他のTRANSACTION ISOLATION LEVELに比べて、DBクライアントの待機時間が長くなりやすい(※1)、デッドロック(※2)が発生しやすい、DBに負荷をかけやすい等、欠点も多いレベルとなっています。
以上の4つのLEVELを機能の有無で表にしてみた。
LEVEL |
ダーティリードの防止 |
選択レコードの保護 |
選択キー範囲の保護 |
READ UNCOMMITTED | なし | なし | なし |
READ COMMITTED | 有り | なし | なし |
REPEATABLE READ | 有り | 有り | なし |
SERIALIZABLE | 有り | 有り | 有り |
※1:MVCC(レコードをバージョン管理することで、ロックを不要にする)が採用されたDBは除く。
(SERIALIZABLEであっても他トランザクションをブロックしないため)
※2:各トランザクションが、お互いに持つ排他的にロックされたレコードを 要求しようとして、ロック解除待ちが永久に続いてしまう現象。
例)
トランザクション1が、レコードAに対してロックを保持し、トランザクション2が、 レコードBに対して排他的ロック(他のトランザクションからのアクセスを排除するロック)を取得したとする。
その後、トランザクション1が、レコードBを取得しようとし、トランザクション2が、レコードAを取得しよう とした場合、どちらもロック解除待ちになってしまい、トランザクションが終わらなくなる。