Ich habe eine MySQL-Update-Abfrage, die manchmal alle Felder aktualisiert und manchmal aktualisiert alle Felder außer einem.Update-Abfrage aktualisiert manchmal Feld in MySQL-Datenbank nicht
Es ist auf etwa 10% der Anrufe fehlgeschlagen.
Mein Tisch ist:
CREATE TABLE IF NOT EXISTS `grades` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`state` int(1) NOT NULL,
`result` varchar(255) NOT NULL,
`date_synced` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`))
ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4395 ;
Meine Frage ist:
$sqlstr = "UPDATE grades SET result = '$result', state = 2, date_synced = '$date', updated_at = '$date' WHERE id = $id";
Wenn es fehlschlägt, Ergebnis date_synced und updated_at aktualisiert aber Zustand bleibt unverändert.
Es gibt eine weitere Abfrage, die nur das Statusfeld aktualisiert und die auch zeitweise fehlschlägt.
Ich konnte das Problem in unserer Testumgebung nicht neu erstellen. Könnte etwas mit der mySQL-Produktionsdatenbank oder einer Art von Kollisionsverriegelung nicht stimmen?
Ich habe weitere Informationen. Ich benutze mysqli. Die andere Abfrage, die nur den Status aktualisiert, verwendet mysql. Würde das ein Problem verursachen?
Ich dachte InnoDB von Zeile gesperrt. Es erlaubt keine partiellen Zeilenaktualisierungen, oder?
Ein weiteres Update, um die Kommentare zu adressieren.
Mein Code-Flow ist ziemlich linear.
The row is created with state=0.
<flash stuff here> and the row is updated with state=1
A cron job pulls all state=1 and sends an api call
if api call is successful, the row is updated with state=2, result, date_synced, and updated_at
if api call is error, the row is updated with state=3, result, and updated_at
Das Statusfeld wird nie wieder auf 0 (nach dem Blitz) oder 1 (nach dem API-Aufruf) eingestellt. Da das Datum _synced und das Ergebnis gesetzt sind, aber (manchmal) der Zustand immernoch 1 ist, ist es so, als ob die Aktualisierung auf das Statusfeld gelöscht wird.
Ich werde den Update-Trigger hinzufügen und sehen, ob das mir mehr Informationen gibt.
sollten Sie einen Aktualisierungstrigger und eine Protokolltabelle hinzufügen, die die alten und neuen Werte zusammen mit der ID, der Sitzungs-ID und dem aktuellen Benutzer zum Debuggen speichert. Vielleicht sind die Änderungen bestanden, wurden aber von einer anderen Anweisung überschrieben. –
Ich denke, Sir Rufos Kommentar könnte für Ihre Situation sehr hilfreich sein, weil er hilft, die Reihenfolge der Dinge zu bestimmen und ob es ein komplexeres Szenario ist, in dem mehrere Abfragen resultieren auf dem Bild, das du siehst. – DWright
"[..] oder eine Art von Kollisionssperrung [..]", da andere Felder in derselben Zeile aktualisiert wurden, haben Sie kein Sperrproblem. Das kleinste, was innodb sperren kann, ist eine Zeile. Ich kann kein einzelnes Feld sperren. – scones