トランザクションの分離レベル
環境 MySQL5.6
MySQLでは、ISOで定められている
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
をInnoDBのみがサポートする。
ISO基準だと以下のような感じだが、InnoDBはファントムリードも発生しないようになっている。
以下の表が簡単な違いのまとめ。
ロストアップデートはISOでは規定されていないが、MySQLでのREPEATABLE READとSERIALIZABLEのわかりやすい違いなので書いておく。
ダーティーリード | ノンリピータブルリード | ファントムリード | ロストアップデート | |
---|---|---|---|---|
READ UNCOMMITTED | あり | あり | あり | あり |
READ COMMITTED | なし | あり | あり | あり |
REPEATABLE READ | なし | なし | あり(InnoDBはなし) | あり |
SERIALIZABLE | なし | なし | なし | なし |
そのためREPEATABLE READではロストアップデートが発生する。
ただしSELECT FOR UPDATEや明示的LOCKを使う事で防ぐことも可能。
※共有ロックはデッドロックを引き起こす可能性があるので注意して使う必要がある。
ダーティーリード |
---|
他のトランザクションで値の変更が有ったとき、まだCOMMITされていなくても変更された結果を読み取る。 |
ノンリピータブルリード(ファジーリード) |
あるトランザクション内で、値が1回目と2回目の読み取りで変わってしまうこと。 ダーティーリードのように、他のトランザクションでのCOMMIT前の値は反映されないが、COMMITされたUPDATE結果が反映され発生する。 |
ファントムリード |
同じトランザクション内で、行数が増減すること。 ダーティーリードや、他のトランザクションのUPDATEは反映されないが、INSERTやDELETEの結果が反映される。 |
ロストアップデート |
あるトランザクションで変更した値を、他のトランザクションが変更すること。 先行した変更は失われる事になる。 |