自分の言葉で垂れ流す。
トランザクションは処理の塊。
データベースへの読み書き(トランザクション処理)には処理時間が発生する。複数のトランザクション処理依頼がデータベース管理システムへ行われたとき、これらを処理する1つの方法は逐次的(Serial)に1つずつトランザクションを処理する方法である。トランザクション処理に処理時間がかかることから、後に行われた処理は先に行われた処理が完了するまでの間「待ち」の状態になってしまう。
待ちを最小化するためにはデータベース管理システムが複数のトランザクションを並行(Concurrent)に処理すればよい。しかしトランザクションは必ずしも安全に並列化できるとは限らない。そのためデータベース管理システムは各並行トランザクションが互いに影響を受けず分離された安全な範囲内でトランザクションを並行化する。あるいは、異常な振る舞い(anomalies)を起こしうる分離レベルが低い並行化を許容し、代わりに並行性を高めてトランザクション処理性能を上昇させる[1]。この安全性・一貫性と性能のトレードオフを生む、並行性トランザクションの分離具合がトランザクション分離レベルである[2]。
トランザクションの並列化の際に、実行中のトランザクション内で発生する問題は以下がある。
- dirty read
- 他のトランザクション内でなされた、コミットまで行っていない「レコードの変更」・「新規作成されたレコード」が見えてしまう
- non-repeatable read
- 他のトランザクション内でなされた「レコードの変更」により、トランザクションの実行中にレコードの値が書き変わってしまう。
- phantom read
- 他のトランザクション内でなされた「レコードの新規作成」により、トランザクションの実行中にテーブル内に新しいレコードが新しく見えるようになる。
これらのどこまでを許容するかは実行するトランザクションの4つの分離レベルとして設定される。
(最も厳しい分離レベルのSerializableだとどれも発生しないが、パフォーマンスが良くない。これらはトレードオフの関係にある。)
- Read uncommitted
- Read committed
- Repeatable read
- Serializable
以下がSQL標準で定義されている対応表。
なお、Serializableは内部で複数のトランザクションが一つずつ実行されているとは限らない。
(from. https://techracho.bpsinc.jp/kotetsu75/2018_12_14/66410)
これらのモードの実行にはテーブルあるいはレコードのロックが使用されているらしい。