トランザクション分離レベル
概要
トランザクションのACID特性の一つである独立性を完全に守ろうとすると、同時実行性能が失われてしまう。
結果、DBの性能がめちゃくちゃ低下することになる。
それを避けるために、大体のRDBMSでは独立性を緩和できるようにして性能を担保しようとしている。
その緩和レベルのことを「トランザクション分離レベル」と呼ぶ。
そして、このトランザクションの分離を実現する手段として、ロックと呼ばれる仕組みが基本利用される。 整合性と性能のトレードオフ
トランザクションにおいては、整合性と性能がトレードオフの関係にある。
分離レベルを緩和すればするほど、同時実行性が高まって性能が上がるが、その分トランザクションの整合性は下がることになる。
以下の表を頭に叩き込んどけ
https://scrapbox.io/files/6398a8e91f15f5001e8a971c.png
この表では分離レベルを下げれば下げるほど、起きる不都合が増えることを表している。
分離レベルを下げると起こる不都合
ダーティリード
あるトランザクションがまだコミットしてない情報を、別トランザクションから読み取れてしまう状態。
まだ変更が確定してない情報を読み取れてしまうと、明らかに不整合が起きることは目に見える。
そのトランザクションがその変更をロールバックしたとしても、別トランザクションからそのデータを読み取って利用してたものは、そのまま突き進んでしまう
ノンリピータブルリード
コミットした情報に関しては読み取れるのだが、トランザクションが終わってない段階で、別トランザクションがデータを変更した場合に不都合が生じる。
トランザクション内でデータAを2回読み取った時、1回目と2回目の読み取りの間に別トランザクションから変更が加えられてると....
トランザクション内でデータAの見た目が変わってしまう
ファントムリード
トランザクション実行中に利用テーブルのレコード数が変更(INSERT、DELETE)された場合に不都合が起きる。
トランザクション内での範囲読み取り結果が変わることになる。
例えば、1回目は4件取得できたのに、途中で別トランザクションからInsertされてしまい、2回目のクエリでは6件取得できてしまった的な。
分離レベルとロックの関係
各分離レベルを実現するためにロックが利用されてる。
ロックだけで各分離レベルを表現してるわけではないが。
例えば、MySQLのInnoDBエンジンだと共有ロックと排他ロックを使って、いい感じに各分離レベルを表現してる。
参考