it-swarm.com.de

SQL Server-Transaktionszeitlimit

Gibt es in SQL Server 2008 R2 eine Möglichkeit, ein Zeitlimit für eine Datenbankänderung mit einer Transaktion zu verursachen? Wir haben ein Szenario, in dem unser Anwendungscode eine Ausnahme hängt oder auslöst und kein Rollback oder Commit ausführt. Dies führt dann dazu, dass andere Sitzungen hängen bleiben und auf den Abschluss der Transaktion warten.

9

Marks Antwort erweitern ...

Wenn ein Client-Timeout-Ereignis auftritt (z. B. .net CommandTimeout), sendet der Client ein "ABORT" an SQL Server. SQL Server gibt dann einfach die Abfrageverarbeitung auf. Es wird keine Transaktion zurückgesetzt, es werden keine Sperren freigegeben.

Jetzt wird die Verbindung an den Verbindungspool zurückgegeben, sodass sie auf SQL Server nicht geschlossen wird. Sollte dies jemals passieren (über KILL oder Client-Neustart usw.), werden die Transaktionen + Sperren gelöscht. Beachten Sie, dass sp_reset_connection sie nicht löscht oder nicht löscht, obwohl dies angekündigt wird

Dieser Abfall aus dem Abbruch blockiert andere Prozesse.

Um SQL Server Transaktionen + Sperren für das Client-Timeout (ausschließlich ABORT-Ereignisse) zu löschen, verwenden Sie SET XACT_ABORT ON.

Sie können überprüfen, ob dies 2 Abfragefenster in SSMS öffnet:

Fenster 1:

Stellen Sie im Menü Query..Query Options ein Timeout von 5 Sekunden ein und führen Sie dieses aus

BEGIN TRAN
UPDATE sometable WITH (TABLOCKX) SET foo = foo WHERE 1 = 0;
WAITFOR DELAY '00:00:10' -- just has to be longer then timeout

Fenster 2, dies wird für immer warten (oder Ihre Zeitüberschreitung treffen)

SELECT * FROM sometable

SET XACT_ABORT ON hat auch interessante Nebenwirkungen:

  • @@ TRANCOUNT wird beim impliziten Rollback auf Null gesetzt, aber der Fehler 266 wird unterdrückt (dies geschieht, wenn @@ TRANCOUNT beim Ein- und Ausstieg aus einem gespeicherten Prozess unterschiedlich ist).
  • XACT_STATE wird -1 sein (es ist "zum Scheitern verurteilt")

Die Kombination davon bedeutet, dass Sie SAVEPOINTS nicht für teilweise Commits/Rollbacks verwenden können (obwohl ich mich nicht an das genaue Verhalten erinnern kann). Welches passt zu mir

SO-Links zu SET XACT_ABORT:

Auf verschachtelten gespeicherten Prozessen:

Bei sp_reset_connection:

20
gbn

Ich beantworte dies mit Zögern, da Ihre Beschreibung des Problems nicht genügend Informationen enthält, um 100% sicher zu sein, dass dies der beste Rat ist. "Hängt oder löst eine Ausnahme aus" deutet darauf hin, dass die Ursache des Problems nicht richtig verstanden wurde. Fahren Sie daher mit Vorsicht fort.

Die einfachste Lösung hierfür ist wahrscheinlich SET XACT_ABORT ON.

XACT_ABORT Legt fest, ob SQL Server im Falle eines Laufzeitfehlers eine Transaktion zurücksetzt. Der Standardwert SET XACT_ABORT OFF Setzt nur die Anweisung zurück, die einen Fehler verursacht hat, und lässt alle übergeordneten Transaktionen offen.

Der "Gotcha" -Nebeneffekt der Standardeinstellung ist, dass ein Timeout genau das gleiche Problem verursachen kann, eine offene Transaktion, für deren Bearbeitung und Rollback der Kunde verantwortlich ist. Wenn der Client nicht versucht/fängt/zurückrollt, bleibt die Transaktion offen, bis die Ultra-Gewalt von KILL <spid> Behandelt wird (und ich zitiere @gbn).

Die oft zitierten Erland Sommarskog's Artikel zu Fehlerbehandlung in SQL Server enthalten alle Hintergründe und Strategien, die Sie für den Umgang mit diesen Szenarien und mehr benötigen.

Bearbeiten (folgender Kommentar): Um offene Transaktionen zu identifizieren, ist sp_whoisactive wahrscheinlich die vollständigste Funktion.

11