- ダーティリード:別のトランザクションからコミットされていないデータを読み取る
- 繰り返し不可の読み取り:
UPDATE
別のトランザクションのクエリからCOMMITTEDデータを読み取ります
- ファントム読み取り:別のトランザクションから、
INSERT
またはDELETE
クエリからCOMMITTEDデータを読み取ります
注:別のトランザクションからのDELETEステートメントも、特定の場合に繰り返し不可の読み取りを引き起こす可能性が非常に低くなります。これは、残念ながらDELETEステートメントが、現在のトランザクションが照会していたのとまったく同じ行を削除したときに発生します。しかし、これはまれなケースであり、各テーブルに数百万の行があるデータベースでは発生する可能性ははるかに低くなります。トランザクションデータを含むテーブルは、通常、実稼働環境ではデータ量が多くなります。
また、ほとんどのユースケースでは、実際のINSERTまたはDELETESではなく、UPDATESの方が頻繁なジョブである可能性があります(このような場合、繰り返し不可の読み取りの危険性が残るだけです- これらの場合、ファントム読み取りは不可能です)。これが、UPDATEがINSERT-DELETEとは異なる方法で処理され、結果として生じる異常の名前も異なる理由です。
また、単にUPDATESを処理するだけでなく、INSERT-DELETEの処理に関連する追加の処理コストもあります。
- READ_UNCOMMITTEDは何も防止しません。ゼロ分離レベルです
- READ_COMMITTEDは、1つだけ、つまりダーティリードを防ぎます。
- REPEATABLE_READは、ダーティリードと繰り返し不可の読み取りの2つの異常を防止します。
- SERIALIZABLEは、ダーティリード、繰り返し不可のリード、ファントムリードの3つの異常をすべて防止します。
次に、トランザクションを常にSERIALIZABLEに設定しないのはなぜですか?さて、上記の質問への答えは次のとおりです:SERIALIZABLE設定はトランザクションを非常に遅くしますが、これは望ましくありません。
実際、トランザクション時間の消費は次の割合です。
SERIALIZABLE > REPEATABLE_READ > READ_COMMITTED > READ_UNCOMMITTED
したがって、READ_UNCOMMITTED設定が最速です。
概要
実際には、ユースケースを分析して分離レベルを決定し、トランザクション時間を最適化してほとんどの異常を防ぐ必要があります。
データベースにはデフォルトでREPEATABLE_READ設定があることに注意してください。