【DB】トランザクション分離レベル
トランザクション分離レベルとは
RDBMSがSQLによる問い合わせ・更新を行う時、トランザクション単位で処理を行う。
トランザクションとは処理の単位を表し、
トランザクションの結果はALL OR NOTHING、すなわち全て実行するか全く実行しないかの二択になる(原子性)。
また、トランザクションで扱われるデータに対しては一貫性が担保される。
たとえばトランザクションAが実行されている間、並列実行しているトランザクションBはAの参照・更新するデータを参照・更新することはできない(ロック)。
ただし、この制約によって並列実行が効率的に行われない場合があるため、実際にはこのデータ一貫性のための制約が緩和される。
この「どれくらいデータの一貫性を犠牲にするか」の程度をトランザクション分離レベルといい、以下の四段階が定義される。
- SERIALIZABLE
- REPEATABLE READ
- READ COMMITED
- READ UNCOMMITED
SELIALIZABLE(直列化可能)
直列化可能。
トランザクション同士が並列に実行されても、直列実行したときと同じ結果が得られる。
例えば、トランザクションAとBのトランザクションレベルがSELIALIZABLEの場合、両者が同時実行されても、Aの後にBを実行したときと結果が同じになる。
REPEATABLE READ(再現性有データ読み込み)
あるトランザクションAが実行されている間、別のトランザクションBによってAの読み取り対象となるデータが変更されることがない。
但し、データそのものが追加・削除された時に、読み取り結果に矛盾が生じる場合がある(ファントムリード)。
READ COMMITED(コミット済みデータ読み込み)
あるトランザクションAが実行されている間、別のトランザクションBによって変更がコミットされたデータのみAは読み取り可能になる。
但し、変更されたデータはトランザクションの途中であるため、何度も変更がかかる。そのため、ファントムリードのリスクに加え、参照するデータに一貫性がなくなる非再現リードのリスクがある。
READ UNCOMMITABLE(非コミット済みデータ読み込み)
あるトランザクションAは、別のトランザクションBによって変更・挿入・削除されている任意のデータを参照できる。
ファントムリード、非再現リードのリスクに加え、不完全なデータを参照するダーティ・リードのリスクがある。