START TRANSACTION
のMySQLドキュメント は次のように述べています。
一貫した読み取りを許可する唯一の分離レベルは、REPEATABLE READです。他のすべての分離レベルでは、WITH CONSISTENT SNAPSHOT句は無視されます。 WITH CONSISTENT SNAPSHOT句が無視されると、警告が生成されます。
SERIALIZABLE
分離レベルがREPEATABLE READ
を超えると、一貫した読み取りが提供されると思ったので、私は驚いています。
WITH CONSISTENT SNAPSHOT
がSERIALIZABLE
トランザクションを処理できない原因は何ですか?
私も 2012年のこのバグレポート を見つけましたが、ドキュメントは最初、これがREPEATABLE READ
とSERIALIZABLE
の両方で機能することを述べ、明示的にREPEATABLE READ
のみに変更しました、これには技術的な理由があるようです。私はそれをテストしましたが、MySQLはSERIALIZABLE
と共に使用すると警告を生成します。
WITH CONSISTENT SNAPSHOT修飾子は、それが可能なストレージエンジンの一貫した読み取りを開始します。
一貫性のある読み取り同時に実行されている他のトランザクションによって実行された変更に関係なく、スナップショット情報を使用して、特定の時点に基づいてクエリ結果を提示する読み取り操作。
SERIALIZABLE分離レベルでは、必要なすべてのデータがトランザクションによってすでにロックされているため、スナップショットを使用する必要はありません。
SERIALIZABLE分離レベルは、REPEATABLE READよりもACIDに準拠している必要があります。これは、2番目のレベルが非ロック読み取りを許可するため、ACIDのI(分離)規則に違反する可能性があるためです。
これは主に私の推測ですが、技術的な理由は、SERIALIZABLE
トランザクションが有効になったときです。
トランザクション分離レベルに関するMySQL 5.7ドキュメント のパラグラフ4によると
ACIDへの準拠が重要な重要なデータの操作では、デフォルトのREPEATABLE READレベルで高度な一貫性を強制できます。
...
SERIALIZABLEはREPEATABLE READよりもさらに厳しい規則を適用し、主に次のような特殊な状況で使用されますXAトランザクション、および並行性とデッドロックに関する問題のトラブルシューティング用。
どのようにしてSERIALIZABLE
にREPEATABLE READ
よりも厳しい整合性ルールを強制させることができますか?同じドキュメントページのSERIALIZABLE
の定義に注意してください。
このレベルはREPEATABLE READに似ていますが、自動コミットが無効になっている場合、InnoDBはすべてのプレーンSELECTステートメントを暗黙的にSELECT ... LOCK IN SHARE MODEに変換します。自動コミットが有効な場合、SELECTは独自のトランザクションです。したがって、読み取り専用であることが知られており、一貫性のある(非ロック)読み取りとして実行され、他のトランザクションをブロックする必要がない場合は、シリアル化できます。 (他のトランザクションが選択された行を変更した場合にプレーンSELECTを強制的にブロックするには、自動コミットを無効にします。)
したがって、違いを確認するには、自動コミットを実験する必要があります。
SERIALIZABLE
で自動コミットを無効にすると、SELECT ... LOCK IN SHARE MODE
が呼び出されて読み取り可能なロックが発生しますが、読み取りが行われる前の特定の段階でREPEATABLE READ
にロックが先制的に表示されます。
自動コミットを有効にすると、ロックなしの読み取りはワイルドに実行され、読み取られるデータは基本的に同じになるため、SERIALIZABLE
はREPEATABLE READ
のように表示されます。
この観点からトランザクションを見ると、共有ロックが停滞しているため、SERIALIZABLE
が一貫しているとは決して言えません。これにより、一貫性が失われます。これが、REPEATABLE READ
が ACID準拠 に使用される唯一の分離レベルである理由です。
したがって、SERIALIZABLE
で作成されたスナップショットは、REPEATABLE READ
とは対照的に、異なる時点で異なって見える可能性があります。