プロジェクトで遭遇したMySql行ロックと同時性関係(3)--deadlockが発生した理由

2525 ワード

ポイントが着きました!Deadlockが発生した理由:
deadlockはデッドロックであり、一般的には2つの同時にトランザクションの接続を加えて互いにUPDATEの相手のロック行を追加し、互いに待つことになる.このような操作は論理的に永遠に実行される.これがデッドロックの概念であるはずだが、データベースはこのような状況を実際に発生させない.このような状況が発生したと判断したとき、MySqlは先に中断し、ロールバックした後に実行された接続を報告し、deadlock異常を報告する.DML操作を先に行う接続も許可されます.例は次のとおりです.
次に、接続1にトランザクションとテーブルTEST_を追加します.ALRのID=1行にロックをかける
SET autocommit=0;
SELECT * FROM TEST_ALR WHERE ID=1 FOR UPDATE;

次に、接続2にトランザクションとテーブルTEST_を追加します.ALRのID=2行に行ロックをかけ、同時にID=4の行をUPDATE操作する
SET autocommit=0;
SELECT * FROM TEST_ALR WHERE ID=2 FOR UPDATE;
UPDATE TEST_ALR SET NAME='ABC' WHERE ID=4;

どちらも正常に実行されました.この2つの接続の間にも影響はありません.
このとき、接続1でID=2行に対してUPDATEを行い、待機タイムアウトが報告されない前に接続2でID=1行に対してUPDATEを行う.
UPDATE TEST_ALR SET NAME='TEST2' WHERE ID=2;
Deadlock found when trying to get lock; try restarting transaction

deadlock異常が発生しました.前に説明した状況が発生したことを示します.
TEST_の表示ALRテーブルID=4のデータ:
SELECT * FROM TEST_ALR WHERE ID=4;
ID
NAME
4
趙六
ロールバックが見つかりました
接続1を再切断して確認すると、接続1のUPDATEが成功して実行されたことがわかります.
1 row(s) affected
以前の項目では同時使用が必要であったため、同時のCALLストレージプロセスが必要であったが、当時のプロセスで書かれていた問題点があり、行ロックは正しくなっていたが、行ロックが完了した後、後のUPDATE操作はインデックス列を条件としていなかったため、接続中に最初に書かれた行ロックはプラスの行ロックであったが、UPDATE操作の際には現在のテーブルに対して表レベルロック操作を行いたいと考え、ただし、他の接続においても同時にこのテーブルに行レベルロックが付加されているため、行レベルロックトランザクションの解除を待つには、ここでUPDATE操作を継続する必要がありますが、一方ではCALLの同じプロセスであるため、同じUPDATE操作が発生します.この2つの接続間で互いに待機している場合、デッドロックが発生します.例は次のとおりです.
接続1と接続2にトランザクションと同行しないロー・ロックが追加されました.
接続1:
SET autocommit=0;
SELECT * FROM TEST_ALR WHERE ID=1 FOR UPDATE;

接続2:
SET autocommit=0;
SELECT * FROM TEST_ALR WHERE ID=2 FOR UPDATE;

このとき接続1ではNAMEを条件としてTEST_ALARMの進行UPDATE(張三は表の中で実は唯一だが、インデックス列ではない):
UPDATE TEST_ALR SET NAME ='  1' WHERE NAME='  ';

待機が見つかり、タイムアウトしていないときに接続2で同じ原理のUPDATEを実行します.
UPDATE TEST_ALR SET NAME ='TEST' WHERE NAME='TEST';

デッドロック異常:
EooroCode:1213
Deadlock found when trying to get lock; try restarting transaction

接線接続1で:
1 row(s) affected
実はTEST_ALRテーブルのNAMEフィールドの「張三」と「TEST」はそれぞれ自分の行に対応するデータですが、UPDATEの操作条件がインデックス列に基づいて操作されていないと、データベースは実際にテーブルのデータを読み取ることができないので、データベースはあなたの条件が以前に加えた行ロックの範囲内にあるかどうか、あるいはUPDATEの操作条件がインデックス列ではないため、テーブルにテーブルレベルロックを追加し直すことになります.互いに待つことによるdeadlock;