InnoDBロックについてのmysqlリファレンスマニュアルを読んでいます。 INSERTは、挿入された行に排他ロックを設定コミットがデッドロックを引き起こさない理由
: ( http://dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.htmlから:)私はそれを得ました。このロックは、次のキーロックではなくインデックスレコードロックです(つまり、ギャップロックはありません)。挿入された行の前に他のセッションがギャップに挿入されることを防ぎません。
前に行を挿入し、ギャップロックのタイプは、インサート意図ギャップロックが設定されていると呼ばれます。このロックは、同じ索引ギャップに挿入された複数のトランザクションが、ギャップ内の同じ位置に挿入されていない場合、互いを待つ必要がないように、挿入の意図を通知します。 4と7の値を持つ索引レコードがあるとします.5と6の値を挿入しようとする個別のトランザクションは、挿入された行の排他ロックを取得する前に、挿入意図ロックで4と7の間のギャップをロックします。行が競合していないため、互いにブロックします。
重複キーエラーが発生した場合、重複したインデックスレコード上の共有ロックが設定されています。このような共有ロックを使用すると、別のセッションがすでに排他ロックを持っている場合に同じ行を挿入しようとするセッションが複数ある場合、デッドロックが発生する可能性があります。これは、別のセッションが行を削除した場合に発生する可能性があります。 InnoDBのテーブルT1には、以下の構造を有すると仮定する:
は、テーブルT1(iはINT、PRIMARY KEY(I))ENGINE = InnoDBテーブルを作成します。
セッション1: は今3つのセッションが順番に次の操作を実行したと
START TRANSACTION;
INSERT INTO t1 VALUES(1);
セッション2:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
セッション3:
START TRANSACTION;
INSERT INTO t1 VALUES(1);
セッション1:
セッション1によってROLLBACK;
最初の動作は、行に対する排他ロックを取得します。セッション2とセッション3による操作の結果、重複キーエラーが発生し、両方がその行の共有ロックを要求します。セッション1がロールバックされると、行に対する排他ロックが解除され、セッション2および3のキューに入れられた共有ロック要求が許可されます。この時点では、セッション2と3はデッドロックしています。他方は共用ロックを保持しているため、行の排他ロックを取得できません。
私は実験を行いましたが、それは事実です。
私の質問は:
(1)私はセッション1をコミットした場合、ことがわかった、とデッドロックが発生しませんでした。どうして?セッション1をコミットすると、X行ロックも解放されます。だから私は理解していない。
Thx。
おそらく、スレッドの1つが排他ロックを取得し、もう1つが「デッドロック」ではなく「待機」でヒットしたため、デッドロックは発生しませんでした.---セッション2とセッション3のいずれかが排他ロック?重複キーエラーが発生した後に共有ロックを要求していませんか? – XiaJun
私はそれがその時点で物事を巻き戻す方法に精通していません。 –