sql >> データベース >  >> RDS >> Mysql

主キーと一意キーを使用したテーブルの予期しないロック

    発生している問題は、MySQLが挿入しようとしている値のテーブル行をロックするだけでなく、前のidの間のすべての可能な値をロックするために発生します。 次のIDを順番に並べて、次の例を再利用します。

    DROP TABLE IF EXISTS foo;
    CREATE TABLE `foo` (
      `i` INT(11) NOT NULL,
      `j` INT(11) DEFAULT NULL,
      PRIMARY KEY (`i`),
      UNIQUE KEY `jk` (`j`) 
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
    INSERT INTO foo VALUES (5,5), (8,8), (11,11);
    

    トランザクションTX1:

    から開始するとします。
    START TRANSACTION;
    REPLACE INTO foo VALUES(8,8);
    

    次に、トランザクションを開始した場合TX2INSERTが何であれ またはREPLACE idを使用する 5〜11がロックされます:

    START TRANSACTION;
    REPLACE INTO foo VALUES(11,11);
    

    MySQLは、ここで説明する「ファントムの問題」を回避するためにこの種のロックを使用しているようです: http://dev.mysql.com/doc/refman/5.0/en/innodb-next-key-locking.html 、MySQLは、インデックス行ロックとギャップロックを組み合わせた「次のキーロック」を使用します。これは、前のIDと次のIDの間で多くの可能なIDをロックし、前のIDと次のIDもロックすることを意味します。 。

    これを回避するには、異なるトランザクションに挿入されたレコードが重複しないように、または少なくともすべてのトランザクションを同時に実行しないようにレコードを挿入するサーバーアルゴリズムを作成して、TXを作成してください。 お互いを待つ必要はありません。



    1. INNERJOINの前のWHERE句

    2. SQLServerで文字列内の各単語の最初の文字を大文字にする最良の方法は何ですか

    3. 別のスキーマのテーブルへの外部キー参照

    4. 複数行の2つの列から値を選択する