Dies ergab sich aus dieser verwandten Frage , bei der ich wissen wollte, wie zwei Transaktionen in einem trivialen Fall (bei dem beide nur in einer einzigen Zeile ausgeführt werden) nacheinander ausgeführt werden können. Ich habe eine Antwort erhalten - SELECT ... FOR UPDATE
als erste Zeile beider Transaktionen verwenden -, aber dies führt zu einem Problem: Wenn die erste Transaktion nie festgeschrieben oder zurückgesetzt wird, wird die zweite Transaktion auf unbestimmte Zeit blockiert. Die innodb_lock_wait_timeout
Variable legt die Anzahl der Sekunden fest, nach denen dem Client, der versucht, die zweite Transaktion durchzuführen, die Meldung "Entschuldigung, versuchen Sie es erneut" mitgeteilt wird. Soweit ich das beurteilen kann, wird er es bis zum nächsten Neustart des Servers erneut versuchen. So:
- Sicherlich muss es eine Möglichkeit geben, eine zu erzwingen,
ROLLBACK
wenn eine Transaktion ewig dauert? Muss ich einen Daemon verwenden, um solche Transaktionen zu beenden, und wenn ja, wie würde ein solcher Daemon aussehen? - Wenn eine Verbindung durch
wait_timeout
oderinteractive_timeout
während der Transaktion unterbrochen wird, wird die Transaktion zurückgesetzt? Gibt es eine Möglichkeit, dies von der Konsole aus zu testen?
Erläuterung : innodb_lock_wait_timeout
Legt die Anzahl der Sekunden fest, die eine Transaktion auf die Freigabe einer Sperre wartet, bevor sie aufgibt. Was ich möchte, ist eine Möglichkeit , die Freigabe eines Schlosses zu erzwingen.
Update 1 : Hier ist ein einfaches Beispiel, das zeigt, warum innodb_lock_wait_timeout
nicht ausreicht, um sicherzustellen, dass die zweite Transaktion nicht von der ersten blockiert wird:
START TRANSACTION;
SELECT SLEEP(55);
COMMIT;
Mit der Standardeinstellung von innodb_lock_wait_timeout = 50
wird diese Transaktion nach 55 Sekunden fehlerfrei abgeschlossen. Wenn Sie UPDATE
vor der SLEEP
Zeile eine hinzufügen und dann eine zweite Transaktion von einem anderen Client initiieren, der versucht, SELECT ... FOR UPDATE
dieselbe Zeile zu erstellen, tritt die zweite Transaktion ab, nicht diejenige, die eingeschlafen ist.
Was ich suche, ist eine Möglichkeit, dem erholsamen Schlaf dieser Transaktion ein Ende zu setzen.
Update 2 : Als Reaktion auf die Bedenken von hobodave, wie realistisch das obige Beispiel ist, gibt es hier ein alternatives Szenario: Ein DBA stellt eine Verbindung zu einem Live-Server her und wird ausgeführt
START TRANSACTION
SELECT ... FOR UPDATE
Dabei sperrt die zweite Zeile eine Zeile, in die die Anwendung häufig schreibt. Dann wird der DBA unterbrochen und geht weg, wobei er vergisst, die Transaktion zu beenden. Die Anwendung wird angehalten, bis die Zeile entsperrt ist. Ich möchte die Zeit minimieren, in der die Anwendung aufgrund dieses Fehlers hängen bleibt.
ROLLBACK
die erste Transaktion erzwingen , wenn der Abschluss länger als n
Sekunden dauert . Gibt es eine Möglichkeit dazu?
MYSQL
es keine Konfiguration gibt, um dieses Szenario zu verhindern. Weil es aufgrund der Verantwortungslosigkeit des Clients nicht akzeptabel ist, dass der Server hängen bleibt. Ich fand keine Schwierigkeit, Ihre Frage zu verstehen, auch sie ist so relevant.