Wollen alle dieselbe Zeile ändern (Gildenlager, begehrtes Item im Auktionshaus, serverweiter Zähler), bekommt immer nur einer den Lock.
Warum Durch ein Event oder ein begehrtes Item häufen sich Änderungen an derselben Zeile → Folge Anfragen warten, bis sie den Lock bekommen → Auf dem Bildschirm Handel schlägt fehl, „Bitte später erneut versuchen“, Timeouts
Zeile aufteilen (Sharded Counter), Transaktionen kurz halten, Änderungen im Speicher sammeln und gebündelt schreiben.
Aufgaben Infrastrukturteam
Wartezeit und Anzahl der Wartevorgänge auf Zeilensperren überwachen, Zeilen mit gehäufter Contention ermitteln und weitergeben.
Größenordnungen
Hält eine Anfrage den Lock 10 ms lang, lässt sich die Zeile höchstens 100-mal pro Sekunde ändern. Enthält die Transaktion zusätzlich einen Round Trip zu einem anderen Server, sinkt dieser Wert entsprechend weiter.
Im Graphen
Steigt mit Spielerzahl und Last · Wartevorgänge auf Zeilensperren (Anzahl, Dauer)
Wo nachsehen
MySQL: Zuwachs von Innodb_row_lock_waits und Innodb_row_lock_time sowie Innodb_row_lock_current_waits prüfen, mit sys.innodb_lock_waits ermitteln, wer auf wen wartet. PostgreSQL: Sessions mit wait_event_type Lock in pg_stat_activity und Anfragen mit granted = false in pg_locks prüfen; mit log_lock_waits (standardmäßig aus) landen lange Lock-Wartezeiten im Log
Spricht dafür
Lock-Wartevorgänge steigen mit Event und Spielerzahl steil an, die meisten wartenden Anfragen zielen auf dieselbe Zeile (denselben Schlüssel) derselben Tabelle
Spricht dagegen
Wartevorgänge gleichmäßig auf viele Tabellen und Zeilen verteilt: eher ausgelasteter Datenträger oder ausgelastete CPU. Eine Session hält einen Lock lange und gibt ihn nicht frei: lange offene Transaktion (db-long-tx)
Prüfmittel
Mit Infrastruktur-Tools prüfbar (ohne Spielcode)
Quellen
InnoDB LockingMySQL Sperrt eine Transaktion eine Zeile (einen Indexeintrag), kann keine andere Transaktion diese Zeile ändern und muss warten
How to Minimize and Handle DeadlocksMySQL Empfehlung, Transaktionen klein und kurz zu halten und direkt nach zusammengehörigen Änderungen zu committen, um Konflikte zu verringern
Server Status VariablesMySQL Innodb_row_lock_waits und Innodb_row_lock_time liefern Anzahl und Dauer der Wartevorgänge auf Zeilensperren, Innodb_row_lock_current_waits die Zahl der aktuell Wartenden