it-swarm.com.de

Sleeping SPID blockiert andere Transaktionen

Ich habe wirklich Probleme, einige Blockierungen aufzuspüren, die wir erleben.

Der Status der Root-Blocking-SPID lautet "Sleeping", der Befehl "AWAITING COMMAND" und "sqltext" SET TRANSACTION ISOLATION LEVEL READ COMMITTED.

Wenn ich den Bericht "Top Transactions by Blocked Transactions Count" ansehe, lautet die Blocking SQL-Anweisung "-".

Ich habe eine Ablaufverfolgung für SQL durchgeführt, und wenn die Blockierung erfolgt, wird die Root-Blockierungs-SPID verfolgt, aber sie hat mich nicht wirklich weitergeführt. Die letzte Trace-Anweisung ist dieselbe wie die sqltext über SET TRANSACTION ISOLATION LEVEL READ COMMITTED.

Ich habe alle zugehörigen gespeicherten Prozeduren überprüft, um sicherzustellen, dass sie über TRY/CATCH BEGIN TRAN-/COMMIT TRAN-/ROLLBACK TRAN-Anweisungen verfügen (wir verwenden gespeicherte Prozeduren für alles, sodass keine eigenständigen Anweisungen ausgeführt werden). Dieses Problem ist erst in den letzten 24 Stunden aufgetreten, und niemand behauptet, Änderungen am System vorgenommen zu haben.

Lösung: Eine unserer selten verwendeten gespeicherten Prozeduren hatte einen Fehler beim Einfügen (Anzahl der Spalten stimmte nicht überein), aber wir sind immer noch verwirrt darüber, was genau passiert ist.

Bei der Betrachtung aller Trace-Informationen wurde die EXEC-Anweisung für diese gespeicherte Prozedur zeitweise aufgeführt, jedoch NIEMALS kurz bevor der BLOCK auf der blockierenden SPID auftrat. Es schien, dass der Trace zu Beginn des Blockierens die Ausführung (oder eine der darin enthaltenen Anweisungen) nicht aufzeichnete. Es gibt jedoch andere Zeiten, in denen der Trace seine Ausführung aufgezeichnet hat und keine Blockierung aufgetreten ist.

Der Fehlerbericht für gespeicherte Prozeduren stammte von einem Benutzer, und ich konnte mehrere EXEC-Anweisungen in Traces finden und in SSMS ausführen. Zu keiner Zeit, als ich sie ausführte, kam es zu einer Blockierung oder sie hingen. Sie wurden wie erwartet ausgeführt (der Catch-Block wurde ausgelöst und die Transaktion nach dem Fehler zurückgesetzt). Nach dem Beheben der Korrektur der gespeicherten Prozedur ist das Problem nicht mehr aufgetreten.

16
Brad

Aus Kommentaren geht hervor, dass Sie ein clientseitiges Befehlszeitlimit hatten, das die SQL-Abfrage abgebrochen hat. Dadurch wird die Transaktion nicht zurückgesetzt, da die Verbindung aufgrund des Verbindungspoolings auf SQL Server geöffnet bleibt.

Sie müssen also SET XACT_ABORT ON verwenden oder einen Client-Rollback-Code hinzufügen

Siehe SQL Server Transaction Timeout für alle wichtigen Details

10
gbn

Verwenden Sie das most_recent_sql_handle in sys.dm_exec_connections, um die zuletzt ausgeführte Anweisung anzuzeigen.

SELECT  t.text,
        QUOTENAME(OBJECT_SCHEMA_NAME(t.objectid, t.dbid)) + '.'
        + QUOTENAME(OBJECT_NAME(t.objectid, t.dbid)) proc_name,
        c.connect_time,
        s.last_request_start_time,
        s.last_request_end_time,
        s.status
FROM    sys.dm_exec_connections c
JOIN    sys.dm_exec_sessions s
        ON c.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(c.most_recent_sql_handle) t
WHERE   c.session_id = 72;--your blocking spid

Überprüfen Sie auch, ob für diesen Spid offene Transaktionen vorhanden sind

SELECT  st.transaction_id,
        at.name,
        at.transaction_begin_time,
        at.transaction_state,
        at.transaction_status
FROM    sys.dm_tran_session_transactions st
JOIN    sys.dm_tran_active_transactions at
        ON st.transaction_id = at.transaction_id
WHERE   st.session_id = 72;--your blocking spid
9
Sebastian Meine

Haben Sie versucht, Adam Machanics sp_whoisactive zu verwenden? Es gibt eine Option, mit der der äußere Befehl überprüft werden kann, ob er sich wirklich in einem Prozess befindet. Es kann sein, dass die Anwendung eine Transaktion offen hält, anstatt sie festzuschreiben. Schauen Sie sich auch DBCC OPENTRAN an.