#これら 4 つの分離レベルでは、複数のトランザクションが同時に競合する場合、ダーティ リードや反復不可能な読み取りが発生する可能性があり、いくつかの問題が発生する可能性があります。ファントム読み取りの問題を解決し、innoDB
は反復読み取り分離レベル モード
ファントム読み取りとは、同じトランザクションで、同じ範囲を 2 回クエリすると得られる結果は一貫性がありません。
図に示すように、最初のトランザクションでは、この時点で範囲クエリを実行します。条件を満たすデータが 1 つだけあり、2 番目のトランザクションでデータ行を挿入して送信します。その後、最初のトランザクションで再度クエリを実行すると、最初のクエリの結果よりも多くの結果が得られます。データの一部である場合、最初のトランザクションの最初と 2 番目のクエリは両方とも同じものであることに注意してください。したがって、ファントム読み取りはデータの一貫性の問題を引き起こします
InnoDB は、ファントム読み取り問題を解決するために ギャップ ロック
と ネクスト キー ロック
メカニズムを導入しました
次のようにします。このような B ツリー インデックス構造があります。この構造には 4 つのインデックス要素、つまり 1、4、7、10 があります。主キー インデックスを通じてレコードをクエリし、このレコードに for update## を渡すと、 #When locking
id=1このインデックスをロックします
# #つまり、このようなステートメントによってトランザクションがロックされた場合、別のトランザクションが実行されます。
このような挿入ステートメントは、以前に取得したトランザクションが Release になるまでブロックする必要があるため、 innonDB で ギャップ ロック
を設計します。その主な機能は、特定の範囲内のインデックス レコードをロックすることです範囲をクエリするときid > 4 および id この範囲がロックされると、
ギャップ ロック が B 番号の (4, 7) の開いた間隔範囲に追加されます。この場合、この範囲内のデータを挿入、更新、または削除する他のトランザクションはロックされますが、この
このクエリ ステートメントは # のような別の状況もあります。 ##id > 4 この条件でロックするには、複数のインデックス範囲をロックする必要があるため、この場合、InnoDB は
next-key lock、next-key lock と呼ばれるメカニズムを導入します。
はギャップ ロックとレコード ロックの組み合わせに相当します。レコード ロックはレコードが存在する行をロックします。ギャップ ロックはレコード行間のギャップをロックし、ネクスト キー ロック
は 2 つの行をロックします。各データ行の一意でないインデックス列の合計
ネクスト キー ロックが設定されます。トランザクションがこれを保持するとき
next-key lock はデータ行に対して使用され、左の開いた範囲と右の閉じた範囲のデータのセクションがロックされます。そのため、id > 4## のような範囲を介してロックする場合は、 #, InnoDB は
next-key lock ロックを追加します。ロック範囲は (4, 7] (7, 10] (10, ♾️]) です。
Gap lock と
next-key lock の違いはロック範囲にあります。
Gap lock は 2 つのインデックス間のギャップをロックしますが、
next-key lock は、
record lock と
gap lock を含む複数のインデックス間隔をロックします。範囲クエリを使用すると、Record レコードにヒットするだけでなく、Gap ギャップも含まれます。この場合、ネクスト キー ロックが使用されます。これは、
next-key lock です。これは、Mysql
のデフォルトの行ロック アルゴリズムです。
以上がMySQL の innoDB でのファントム読み取りを解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。