takafumi blog

日々の勉強メモ

トランザクションの分離レベル

環境   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 なし なし なし なし

SERIALIZABLEでは読み取り時に行をロックし、REPEATABLE READはしない。
そのためREPEATABLE READではロストアップデートが発生する。
ただしSELECT FOR UPDATEや明示的LOCKを使う事で防ぐことも可能。
※共有ロックはデッドロックを引き起こす可能性があるので注意して使う必要がある。


ダーティーリード
他のトランザクションで値の変更が有ったとき、まだCOMMITされていなくても変更された結果を読み取る。
ノンリピータブルリード(ファジーリード)
あるトランザクション内で、値が1回目と2回目の読み取りで変わってしまうこと。
ダーティーリードのように、他のトランザクションでのCOMMIT前の値は反映されないが、COMMITされたUPDATE結果が反映され発生する。
ファントムリード
同じトランザクション内で、行数が増減すること。
ダーティーリードや、他のトランザクションのUPDATEは反映されないが、INSERTやDELETEの結果が反映される。
ロストアップデート
あるトランザクションで変更した値を、他のトランザクションが変更すること。
先行した変更は失われる事になる。