Ich habe eine Tabelle 'klickt', wo ich den Datensatz jedes Mal hinzufügen, wenn Benutzer spezielle Zähler Skript click.php navigiert. Diese Tabelle hat keine Autoinkrement-Spalte. Sie hat transaction_id CHAR(32)
als Primärschlüssel, der vor dem Einfügen eines neuen Datensatzes zufällig generiert wird. Jeder neue Datensatz hat die Spalte normalized=0
.MYSQL: Deadlock mit einfachen Abfragen
Alle 3 Minuten Hintergrund Daemon startet eine Transaktion, liest alle neuen Klicks WHERE normalized=0
und gruppiert es in Tabelle stats
. Die einzige Schreibabfrage für diese Tabelle ist UPDATE clicks SET normalized=1 WHERE normalized=0
, die am Ende aller Verarbeitungen ausgeführt wird und dann die Transaktion festschreibt.
Problem ist, dass jedes Mal, wenn click.php während dieser Transaktion navigiert wird, kann das Skript nicht um einen neuen Datensatz ‚Klicks‘ hinzufügen und wird mit Fehler:
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'
Ich weiß, dass ich dieses Problem lösen kann mit LOCK TABLES
, aber ich möchte nur wissen, warum dieser Deadlock auftritt.
UPD: Ich sehe folgenden Grund in SHOW ENGINE BDB STATUS-Ausgang:
*** (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