it-swarm.com.de

ROLLBACK nach COMMIT

Ich habe mehrere Datenbanksitzungen, von denen eine andere aufgrund einer eingefrorenen Anwendung blockiert hat. Es werden Transaktionen in mehreren Sitzungen ausgeführt. Ich muss den Kopfblocker wegen Zeitüberschreitungen bei Sperranforderungen in anderen Sitzungen beenden. Nach dem Beenden dieser Sitzung haben andere Benutzer Datenverlust gemeldet. Ich bin mir ziemlich sicher, dass sie ihre Transaktionen festgeschrieben haben, aber sie scheinen immer noch zurückgesetzt worden zu sein. Sie können es sogar prüfen, weil einige Dokumente gedruckt wurden, denen später Daten fehlen.

Ist es möglich, dass festgeschriebene Transaktionen aufgrund eines Rollbacks in einer anderen Sitzung zurückgesetzt werden? Ich würde nicht denken, aber nach dem Lesen der COMMIT-Dokumentation habe ich Zweifel. Es sagt:

Wenn @@ TRANCOUNT größer als 1 ist, verringert COMMIT TRANSACTION @@ TRANCOUNT nur um 1 und die Transaktion bleibt aktiv.

Beim Lesen der TRANCOUNT-Dokumentation heißt es:

Gibt die Anzahl der BEGIN TRANSACTION-Anweisungen zurück, die bei der aktuellen Verbindung aufgetreten sind.

Ist die aktuelle Verbindung also dasselbe wie eine Sitzung oder können mehrere Sitzungen dieselbe Verbindung gemeinsam nutzen (möglicherweise durch Pooling)? Und wenn sie teilen können, wie hängt das mit Transaktionen zusammen? Kann es sein, dass diese aktiven Transaktionen später und auch nach ihrer Festschreibung zurückgesetzt werden?

[Bearbeiten] Um es klarer zu machen, haben einige Benutzer kein Sperrzeitlimit erhalten, da ihre Daten nicht mit dem Kopfblocker in Konflikt standen. Sie haben Transaktionen begangen, aber diese Transaktionen schienen zurückgesetzt worden zu sein, nachdem der Kopfblocker getötet worden war.

[Update 2018-03-29] Nach einem neuen Vorfall hatte ich die Gelegenheit, das Problem zu untersuchen, während es passierte. Die Transaktionsprotokolle kamen zu dem Schluss, dass das Problem eine verschachtelte Transaktion war, die niemals festgeschrieben wurde. Die Anwendung, die das Problem verursacht hat, wurde nicht eingefroren, sodass der Benutzer es erst bemerkte, als er die Anwendung schloss. Zu diesem Zeitpunkt verlor er seine Daten, weil die Transaktion zurückgesetzt wurde. Ich akzeptierte die bestmögliche Antwort und diese sagte mir, dass es nicht möglich war, eine festgeschriebene Transaktion zurückzusetzen. Ich denke, es ist wirklich nicht möglich, es ist nur schwer, das eigentliche Problem zu finden.

4
Martin

Im Allgemeinen ist eine Transaktion genau eine von

  • engagiert sein
  • zurückgerollt

Festgeschriebene Transaktionen werden niemals zurückgesetzt.
So funktionieren alle RDBMS nach ACID-Prinzipien

Nun, es gibt verschiedene Fälle, in denen es so aussieht, als ob diese Regel verletzt wurde. Aber es hat nicht.

Bevor wir uns diese Fälle ansehen, teilen verschiedene Benutzersitzungen keine Verbindung. Jeder Benutzer/Client hat eine Verbindung zum SQL und alle sind voneinander isoliert. Das Verbindungspooling hat keinen Einfluss darauf.

Speicherpunkte

Sie können eine Transaktion SPEICHERN und auf diesen Sicherungspunkt zurücksetzen.

Das heißt, Sie können teilweise ein Commit/Rollback durchführen, wenn Sie Sicherungspunkte verwenden, aber ich habe noch nie jemanden gesehen, der dies im realen Code tut. Ich werde nicht mehr expandieren.

Verschachtelte Transaktionen

Sie können Transaktionen verschachteln, aber sie haben eigentlich keine Bedeutung
Einfach ausgedrückt, SQL Server verfügt nicht wirklich über verschachtelte Übergänge, selbst wenn @@ TRANCOUNT höher als eins sein kann.

  • Ein Anfang erhöht @@ TRANCOUNT um eins
  • Ein Rollback setzt @@ TRANCOUNT auf Null
  • Ein Commit verringert @@ TRANCOUNT um eins

Eine längere Erklärung finden Sie in this SO answer

11
gbn

1) Zum Thema Rollback festgeschriebener Transaktionen. Die Dokumentation, auf die Sie verwiesen haben, wenn @@ TRANCOUNT größer als 1 ist, würde auftreten, wenn Sie in einer einzelnen Sitzung Transaktionen verschachteln. https://technet.Microsoft.com/en-us/library/ms189336%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396

In diesem Fall würde die endgültige Transaktion ihre Arbeit und alle verschachtelten Transaktionen festschreiben oder zurücksetzen.

2) Was Sie beschrieben haben, sind mehrere Sitzungen, die mehrere Transaktionen starten möchten, aber blockiert werden. Sie stellen einen Datenverlust fest, weil für die anfordernde Transaktion keine kompatible Sperre verfügbar war und die Anwendung ihre Daten nicht speichern konnte. Ich habe den Begriff "Datenverlust" verwendet, da es sich wirklich um ein Anwendungsproblem handelt. Die Anwendung sollte codiert sein, um zu erkennen, dass eine Transaktion fehlgeschlagen ist, und die Transaktion erneut zu versuchen oder den Endbenutzer zu warnen, damit es keine Überraschungen gibt.

Die Datenbank-Engine hat genau das getan, wofür sie entwickelt wurde, und einen Verstoß gegen das ACID-Prinzip verhindert.

1
Steve Hansen