毎回「なんだっけ」ってなるのでメモ。
トランザクション分離レベルとは?
トランザクションを複数同時に実行するとき、「どれだけ影響を分離させるか?」の設定のこと。
SERIALIZABLE (シリアライズ可能)
「絶対に分離する」なレベル。
たとえば、トランザクションAとトランザクションBを同時に実行しているとき、「Aでデータを読み取り/変更(追加/削除/更新)すると、それらのデータはAが終わるまでBで一切処理できない」になります。
REPEATABLE READ (リピータブル・リード)
SQLのデフォルト。
このモードだと、ファントムリードという現象が発生します。
- ファントムリード:
トランザクションAとトランザクションBを同時に実行しているとき、Aでデータを追加/削除してコミットすると、Bのほうでも反映されちゃう現象
SERIALIZABLEと違ってデータの読み取りだけではロックされません。たとえば「Aでデータを読み取りすると、それらのデータはAが終わるまでBで一切処理できない」にはなりません。読み取りは許されます。
SERIALIZABLEには以下のように書かれているからです👇
SERIALIZABLEは
REPEATABLE READ
と似ていますが、autocommit
が無効になっている場合、InnoDB
はすべてのプレーンSELECT
ステートメントをSELECT ... FOR SHARE
に暗黙的に変換します。引用:https://dev.mysql.com/doc/refman/8.0/ja/innodb-transaction-isolation-levels.html
READ COMMITTED (コミット読取り)
このモードだと、ファントムリードに加えて、ファジーリードという現象も発生します。
- ファジーリード:
トランザクションAとトランザクションBを同時に実行しているとき、Aでデータを更新してコミットすると、Bのほうでも反映されちゃう現象
ファントムリードと違うのは、追加/削除ではなく更新という点。
たとえば、トランザクションBの最初で👿さんの預金残高を読み取ったら1万円だった。でもトランザクションBを処理中にトランザクションAによって残高が0円に変更された。そしてトランザクションBが終わるころにもう一度👿さんの預金残高を読み取ったら0円になってた。
・・みたいなことがおこる。
要するに、おいおい1万円ある前提で処理を進めちゃったじゃん!みたいなことが起こり得る。
READ UNCOMMITTED (非コミット読取り)
「ぜんぜん分離しない」なレベル。
このモードだと、さきほどの
- ファジーリード
- ファントムリード
に加えて、ダーティリードと呼ばれる現象も発生します。
- ダーティリード:
トランザクションAとトランザクションBを同時に実行しているとき、Aでコミットしていない変更を、Bで読み取れてしまうヤバイ現象
「ロールバックしたときどうするんだ」って感じですし、どういうシーンで使うんだろう。
おわり
コメント