Dies sind zwei Kommentare, die mit derselben content_id eingefügt werden. Allein durch das Einfügen des Kommentars wird eine SHARE-Sperre für die Inhaltszeile aufgehoben, um zu verhindern, dass eine andere Transaktion diese Zeile löscht, bis die erste Transaktion abgeschlossen ist.
Der Trigger fährt dann jedoch fort, die Sperre auf EXCLUSIVE zu aktualisieren, und dies kann durch eine gleichzeitige Transaktion blockiert werden, die denselben Prozess ausführt. Betrachten Sie die folgende Abfolge von Ereignissen:
Txn 2754 Txn 2053
Insert Comment
Insert Comment
Lock Content#935967 SHARE
(performed by fkey)
Lock Content#935967 SHARE
(performed by fkey)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2053's share lock)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2754's share lock)
Also- Deadlock.
Eine Lösung ist sofort Nehmen Sie vorher eine exklusive Sperre für die Inhaltszeile vor Kommentar einfügen. d.h.
SELECT 1 FROM content WHERE content.id = 935967 FOR UPDATE
INSERT INTO comment(.....)
Eine andere Lösung besteht einfach darin, dieses Muster der „zwischengespeicherten Zählungen“ vollständig zu vermeiden, es sei denn, Sie können nachweisen, dass es für die Leistung erforderlich ist. Wenn dies der Fall ist, ziehen Sie in Betracht, die zwischengespeicherte Anzahl an einer anderen Stelle als der Inhaltstabelle aufzubewahren, z. ein spezieller Tisch für die Theke. Dadurch wird auch der Aktualisierungsverkehr für die Inhaltstabelle jedes Mal reduziert, wenn ein Kommentar hinzugefügt wird. Oder wählen Sie einfach die Anzahl erneut aus und verwenden Sie memcached in der Anwendung. Es kommt nicht um die Tatsache herum, dass, wo auch immer Sie diese zwischengespeicherte Zählung speichern, ein Engpass sein wird, sie muss sicher aktualisiert werden.