私はテーブル「クリック」があり、ユーザーが特別なカウンタースクリプトclick.phpをナビゲートするたびにレコードを追加します。この表には自動インクリメント列がありません。transaction_id CHAR(32)
が主キーとして使用されていますが、これは新しいレコードを挿入する前にランダムに生成されます。それぞれの新しいレコードには列normalized=0
があります。MYSQL:簡単なクエリでのデッドロック
3分ごとのバックグラウンドデーモンがトランザクションを開始し、すべての新規クリックWHERE normalized=0
を読み取り、テーブルstats
にグループ化します。そのテーブルの書き込みクエリは、すべての処理の最後に実行された後にトランザクションコミットされるUPDATE clicks SET normalized=1 WHERE normalized=0
です。
問題がclick.phpが、このトランザクション中にナビゲートされるたびに、スクリプトは「クリック」に新しいレコードを追加することができないということであり、エラーで失敗します。
SQLSTATE[40001]: Serialization failure:
1213 Deadlock found when trying to get lock; try restarting transaction
INSERT `clicks`
SET `transaction_id`='3520359d597ba05b635ff15feb334229',
`time`='2016-04-29 15:14:31',
...,
`normalized`='0'
私はこの問題を解決することができます知っていますLOCK TABLES
を使用していますが、なぜこのデッドロックが発生するのかを知りたいだけです。
UPD: 私は、SHOW ENGINEのINNODBのSTATUS出力の理由は、以下を参照してください:
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 252763 page no 124 n bits 480 index `normalized`
of table `tds`.`clicks` trx id C1329EF lock_mode X locks gap before
rec insert intention waiting