2 つのテーブルがあり、1 つは多対多の関係 (fooBarTable
列fooId
と) を持ち、もう 1 つは列を持つbarId
InnoDB テーブルで、 inの出現を数えます。fooCounterTable
fooId
counter
fooId
fooBarTable
barId
からすべての を削除するときは、それに応じfooBarTable
て を更新する必要がありfooCounterTable
ます。
私が最初に試したのはこれでした:
UPDATE fooCounterTable SET counter = counter - 1
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId);
しかし、私はこのエラーが発生しました:
MySQL error (1205): Lock wait timeout exceeded; try restarting transaction
を追加するときにテーブルを更新するbarId
と、次の SQL ステートメントで正常に動作します。
INSERT INTO `fooCounterTable` (fooId, counter) VALUES (42,1), (100,1), (123,1)
ON DUPLICATE KEY UPDATE counter = counter + 1;
だから私はカウンターを減らすときに同じことをするだろうと思った.
INSERT INTO `fooCounterTable` (SELECT fooId, 0 FROM fooBarTable WHERE barId = 42 ORDER BY fooId)
ON DUPLICATE KEY UPDATE counter = counter - 1;'
ほとんどの場合、これでうまくいくようですが、デッドロックが発生することがあります。
MySQL error (1213): Deadlock found when trying to get lock; try restarting transaction
だから私はデッドロックについて読んで、それを知りSELECT ... FOR UPDATE
、これを試しました:
START TRANSACTION;
SELECT fooId FROM fooCounterTable
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId) FOR UPDATE;
UPDATE fooCounterTable SET counter = counter - 1
WHERE fooId IN (SELECT fooId FROM fooBarTable WHERE barId = 42 ORDER BY fooId);
COMMIT;
その結果:
MySQL error (2014): commands out of sync
誰でも私の問題を解決する方法を教えてもらえますか?
アップデート
必須の UPDATE ステートメントを実行する前に SELECT ステートメントの結果を使用および解放しなかったため、最後のエラー (2014) が発生しました。私はそれを修正し、エラー 2014 を取り除きましたが、時々デッドロック (エラー 1205) が発生し、理由がわかりません。