なぜMySQLのInnoDBの更新プログラムは、ギャップロックを設定しますか?

Jacky1205:

私の知る限り、ギャップロックを知っているように、ファントム読み取りを防止するために使用される、と私はギャップロックがGoogle検索を経由して、ほとんどの記事で読み取りをロックして設定されて発見されました。

ギャップロックは、インデックスレコード、または最初または最後のインデックスレコード前後のギャップのロックの間のギャップのロックです。例えば、UPDATE FOR 10と20との間のT WHERE C1 FROM C1を選択します。範囲内のすべての既存の値の間の隙間がロックされるので、列の任意のこのような値が既に存在したか否かを、カラムt.c1に15の値を挿入することを防止する他のトランザクションを。

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html#innodb-gap-locks

私はこの(読み取りロックにセットギャップロック)は十分だと思います。なぜ、更新削除、セットギャップロックを。

...セットUPDATE ... 排他ネクストキーロックをすべてのレコードに検索出会いを。しかし、唯一のインデックスレコードロックは、ユニークな行を検索するための一意のインデックスを使用して行をロックする書類に必要です。

https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

そして、もう一つの問題は、ギャップロックを接続できる適切なインデックスが存在しない場合は何が起こっているのですか?テーブル全体のロックへのフォールバックしていますか?

ここでは、デフォルトのトランザクション分離レベル反復可能読み取りを使用していることを仮定しました。

ビルKarwin:

それはあなたのSELECT、UPDATE、またはDELETEの状況に依存します。彼らは、条件にマッチしたことになるセットに行を追加することから、他の同時セッションを防ぐために、ギャップロックを設定します。

InnoDBのでは、ロックのステートメントは、常に最新のコミット行バージョンをロックします。そこで、彼らは本当にREPEATABLE READのスナップショットに従いません。彼らはより多くのREAD-COMMITTEDのように振る舞います。

そのため、あなたはこのようなステートメントを実行する場合:

UPDATE FROM MyTable SET ... WHERE created_at > '2020-03-22';

これは、新しい行を追加することから、他のセッションを防ぐことができますのcreated_atの最高値は、以下のギャップをロックする必要があります。

これがすることですシミュレートあなたは再び同じUPDATEを実行する場合、それは同じ行に影響を与えることを確認するために、REPEATABLE READを、それが誤って新しい行には影響しません。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=373024&siteId=1
おすすめ