Was bewirkt es, wenn eine Transaktion in MSSQL zu lange geöffnet ist?


11

Ich frage mich nur, was passiert, wenn Sie eine Transaktion in einer Datenbank beginnen und vergessen haben, sie festzuschreiben oder zurückzusetzen. Fällt der Server aus? Nehmen wir an, Sie haben es 3 Tage lang liegen lassen.

Es gibt auch Benutzer, die davon ausgehen, dass die anderen Benutzer nicht wissen, dass eine nicht abgeschlossene Transaktion vorliegt (nehmen wir nur an, dass die Benutzer nur Daten in die Datenbank einfügen). Was sind die Konsequenzen dieser Aktion?

Antworten:


14

Eine offene Transaktion für sich allein hat fast keine Konsequenzen. Eine einfache

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

enthält im schlimmsten Fall einige Bytes an Statuswerten. Keine große Sache.

Die meisten Programme erledigen die eigentliche Arbeit innerhalb der Transaktion, und dies ist eine andere Sache. Der Sinn einer Transaktion ist, dass Sie sicher sein können, dass mehrere Fakten in der Datenbank gleichzeitig wahr sind, obwohl andere Benutzer gleichzeitig in dieselbe Datenbank schreiben.

Nehmen Sie das kanonische Beispiel des Geldtransfers zwischen Bankkonten. Das System muss sicherstellen, dass das Quellkonto vorhanden ist, über ausreichende Mittel verfügt, dass das Zielkonto vorhanden ist und dass sowohl Lastschrift als auch Gutschrift erfolgen oder beides nicht erfolgt. Es muss dies garantieren, während andere Transaktionen stattfinden, vielleicht sogar zwischen diesen beiden Konten. Das System stellt dies sicher, indem es die betreffenden Tabellen sperrt . Welche Schlösser genommen werden, und wie viel von anderen Leuten Arbeit , die Sie sehen, wird durch die Transaktion gesteuert Isolationsstufe .

Wenn Sie also viel arbeiten, besteht eine gute Chance, dass andere Transaktionen in die Warteschlange gestellt werden und auf die Objekte warten, für die Sie Sperren haben. Dies verringert den Gesamtdurchsatz des Systems. Irgendwann stoßen sie an Zeitlimits und versagen, was ein Problem für das gesamte Systemverhalten darstellt. Wenn Sie eine optimistische Isolationsstufe verwenden, schlägt Ihre Transaktion möglicherweise fehl, wenn Sie ein Commit aufgrund der Arbeit anderer ausführen.

Das Halten von Sperren beansprucht Systemressourcen. Dies ist der Speicher, den das System nicht zum Verarbeiten anderer Anforderungen verwenden kann, wodurch der Durchsatz verringert wird.

Wenn eine Menge Arbeit hat sich das System durchgeführt wurde kann wählen auszuführen Sperreneskalation . Anstatt einzelne Zeilen zu sperren, wird die gesamte Tabelle gesperrt. Dann sind mehr gleichzeitige Benutzer betroffen, der Systemdurchsatz sinkt weiter und die Auswirkungen auf die Anwendung sind größer.

Datenänderungen werden in die Protokolldatei geschrieben, ebenso wie die Sperren, die sie schützen. Diese können erst aus dem Protokoll gelöscht werden, wenn die Transaktion festgeschrieben wurde. Daher kann eine sehr lange Transaktion dazu führen, dass die Protokolldatei mit den damit verbundenen Problemen aufgebläht wird.

Wenn die aktuelle Arbeit Tempdb verwendet, was für große Arbeitslasten wahrscheinlich ist, sind die Ressourcen dort möglicherweise bis zum Ende der Transaktion gebunden. In extremen Fällen kann dies dazu führen, dass andere Aufgaben fehlschlagen, da nicht mehr genügend Platz für sie vorhanden ist. Ich hatte Fälle, in denen ein schlecht codiertes UPDATE Tempdb füllte, so dass nicht genügend Speicherplatz für die SORT eines Berichts vorhanden war und der Bericht fehlschlug.

Wenn Sie die Transaktion ROLLBACKEN oder das System ausfällt und sich erholt, hängt die Zeit, die das System benötigt, um wieder verfügbar zu sein, davon ab, wie viel Arbeit geleistet wurde. Das Öffnen einer Transaktion wirkt sich nicht auf die Wiederherstellungszeit aus, sondern darauf, wie viel Arbeit geleistet wurde. Wenn die Transaktion offen war, aber eine Stunde lang inaktiv war, erfolgt die Wiederherstellung fast augenblicklich. Wenn für diese Stunde konstant geschrieben wurde, gilt als Faustregel, dass die Erholungszeit ebenfalls etwa eine Stunde beträgt.

Wie Sie sehen können, kann eine lange Transaktion problematisch sein. Bei OLTP-Systemen empfiehlt es sich, eine Datenbanktransaktion pro Geschäftstransaktion durchzuführen. Für die Eingabe von Batch-Workprozessen in Blöcken mit häufigen Festschreibungen und Neustartlogik. Normalerweise können mehrere tausend Datensätze in einer einzelnen DB-Transaktion verarbeitet werden. Dies sollte jedoch auf Parallelität und Ressourcenverbrauch überprüft werden.

Seien Sie nicht versucht, in die andere Richtung zu gehen und Transaktionen und Sperren gänzlich zu vermeiden. Wenn Sie die Konsistenz Ihrer Daten gewährleisten müssen (und warum sollten Sie sonst eine Datenbank verwenden?), Erfüllen Isolationsstufen und Transaktionen einen sehr wichtigen Zweck. Erfahren Sie mehr über Ihre Optionen und entscheiden Sie, mit welchem ​​Gleichgewicht von Nebenläufigkeit und Korrektheit Sie für jeden Teil Ihrer Anwendung leben möchten.


auch wenn es drei tage geöffnet ist?
JanLeeYu

Ja, sogar für drei Tage. Der wichtige Punkt ist die Menge an Arbeit, die bei geöffnetem TX geleistet wurde, und nicht nur, wie lange das TX geöffnet war. Natürlich möchten Sie als DBA möglicherweise den Eigentümer der Transaktion fragen, warum diese so lange geöffnet sein muss. Als ich ein DBA-Team leitete, habe ich alle Sendungen protokolliert, die länger als 30 Minuten geöffnet waren und ein Gespräch mit dem Eigentümer geführt haben.
Michael Green

IN ORDNUNG. Danke für die tolle Erklärung. Obwohl alle das auch großartig gemacht haben.
JanLeeYu

Was für eine Erleichterung ... Nochmals vielen Dank für die Antwort.
JanLeeYu

"Schlecht codiertes UPDATE" Jawohl. Das gesehen. Eine update-Anweisung in einer Schleife, die einige Namen nicht qualifiziert und zu einem 1 = 1-ähnlichen Verhalten geführt hat. Daher wurde die gesamte Tabelle für jede Iteration der Schleife aktualisiert (wodurch auch in den meisten dieser Zeilen die falschen Daten gespeichert wurden).
jpmc26

6

Ihre größte Konsequenz ist das Sperren der in der Transaktion verwendeten Objekte. Insbesondere wenn Sie davon ausgehen, dass Ihre Benutzer Daten einfügen, kann diese lang laufende Transaktion SELECT-Anweisungen für häufig verwendete Tabellen enthalten. Die Aktualisierungsanweisungen Ihrer Benutzer erhalten möglicherweise nicht die erforderliche Sperre, um die Aktualisierungen oder Einfügungen abzuschließen.

Eine sekundäre Sache, die passieren könnte, ist die Protokolldateiaktivität. Wenn Sie beispielsweise ein großes Dataset aktualisieren, bleibt der Teil des Protokolls, den die Transaktion verwendet, für die Dauer dieser Transaktion aktiv. Sie können diesen Teil des Protokolls erst wieder verwenden, wenn die Transaktion festgeschrieben oder zurückgesetzt wurde. In Szenarien, in denen Sie sich möglicherweise in einem stark aktiven OLTP-System befinden, kann dies dazu führen, dass Ihre Protokolldatei schnell wächst und Ihr Speichergerät voll wird.


Wenn beispielsweise derjenige, der die Transaktion erstellt hat, vom Server getrennt wird, kann er sich dann erneut beim Server anmelden, um die Transaktion zu schließen.
JanLeeYu

Es hängt davon ab, ob es sich bei der Transaktion in einer Umgebung, in der MSDTC verwendet wurde, um eine verwaiste Transaktion handelt. In diesem Fall kann der Benutzer es nicht mehr selbst schließen. Der Datenbankadministrator müsste eingreifen, um damit umzugehen. Darüber hinaus sollte die Transaktion in der Regel von SQL Server abgebrochen werden, wenn die Verbindung getrennt wird. Bei umfangreichen Transaktionen ist dies jedoch möglicherweise nicht immer der Fall.

Kann der Administrator in diesem Fall die Transaktion trotzdem abschließen?
JanLeeYu

Das kann ich nicht beantworten, das hängt alles davon ab. Ich hatte Fälle, in denen der Server neu gestartet werden musste oder die Instanz auf einen sekundären Knoten / ein sekundäres Replikat umgeschaltet wurde.

4

Eine unvollständige Transaktion kann eine große Anzahl von Sperren enthalten und zum Blockieren führen

Wenn eine Transaktion nicht abgeschlossen wird, weil eine Abfrage das Zeitlimit überschreitet oder weil der Stapel mitten in einer Transaktion abgebrochen wird, ohne dass eine COMMIT- oder ROLLBACK-Anweisung zum Abschließen der Transaktion ausgegeben wird, bleibt die Transaktion offen, und alle während dieser Transaktion erlangten Sperren werden fortgesetzt gehalten werden. Nachfolgende Transaktionen, die unter derselben Verbindung ausgeführt werden, werden als verschachtelte Transaktionen behandelt, sodass nicht alle in diesen abgeschlossenen Transaktionen erworbenen Sperren freigegeben werden. Dieses Problem wiederholt sich mit allen Transaktionen, die über dieselbe Verbindung ausgeführt werden, bis ein ROLLBACK ausgeführt wird. Infolgedessen wird eine große Anzahl von Sperren aufrechterhalten, Benutzer werden blockiert und Transaktionen gehen verloren, was zu Daten führt, die sich von Ihren Erwartungen unterscheiden.

Quelle


Wenn beispielsweise derjenige, der die Transaktion erstellt hat, vom Server getrennt wird, kann er sich dann erneut beim Server anmelden, um die Transaktion zu schließen.
JanLeeYu

Sobald SQL Server weiß, dass die Verbindung unterbrochen wurde, wird die Transaktion zurückgesetzt. Siehe hier dba.stackexchange.com/questions/47404/… . Wenn derselbe Benutzer erneut eine Verbindung herstellt, handelt es sich um eine andere Sitzung, sodass die alte Transaktion nicht übernommen werden kann.
Michael Green
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.