Von einer .NET 3.5 / C # -App möchte ich abfangen, SqlException
aber nur, wenn dies durch Deadlocks auf einer SQL Server 2008-Instanz verursacht wird.
Typische Fehlermeldung ist Transaction (Process ID 58) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Es scheint jedoch kein dokumentierter Fehlercode für diese Ausnahme zu sein.
Das Filtern einer Ausnahme gegen das Vorhandensein des Deadlock- Schlüsselworts in der Nachricht scheint ein sehr hässlicher Weg zu sein, um dieses Verhalten zu erreichen. Kennt jemand den richtigen Weg dazu?
.net
sql-server-2008
deadlock
try-catch
sqlexception
Joannes Vermorel
quelle
quelle
select * from master.dbo.sysmessages where error=1205
Antworten:
Der Microsft SQL Server-spezifische Fehlercode für einen Deadlock lautet 1205. Sie müssen also die SqlException behandeln und dies überprüfen. Also, zB wenn für alle anderen Arten von SqlException die Blase die Ausnahme sein soll:
Oder verwenden Sie die in C # 6 verfügbare Ausnahmefilterung
Um den tatsächlichen SQL-Fehlercode für eine bestimmte Nachricht zu finden, sollten Sie in sys.messages in SQL Server nachsehen.
z.B
Eine alternative Methode zum Behandeln von Deadlocks (ab SQL Server 2005) besteht darin, dies innerhalb einer gespeicherten Prozedur mithilfe der TRY ... CATCH-Unterstützung zu tun:
Es gibt ein vollständiges Beispiel hier in MSDN, wie Deadlock Wiederholungslogik rein in SQL zu implementieren.
quelle
SqlException
kann die in eine andere eingeschlossen werden. Daher müssen wir möglicherweise jede Art von Ausnahme abfangen und sie überprüfen. Wenn es sich nicht direkt um eine Deadlock-Ausnahme handelt, müssen Sie sie rekursiv überprüfenInnerException
.Da Sie möglicherweise Deadlocks erkennen möchten, um den fehlgeschlagenen Vorgang wiederholen zu können, warne ich Sie gerne vor einem kleinen Problem. Ich hoffe, Sie entschuldigen mich dafür, dass ich hier ein bisschen vom Thema abkomme.
Ein von der Datenbank erkannter Deadlock führt ein Rollback der Transaktion durch, in der Sie ausgeführt wurden (falls vorhanden), während die Verbindung in .NET geöffnet bleibt. Wenn Sie diesen Vorgang (in derselben Verbindung) wiederholen, wird er in einem transaktionslosen Kontext ausgeführt, was zu einer Beschädigung der Daten führen kann.
Es ist wichtig, sich dessen bewusst zu sein. Es ist am besten, die vollständige Verbindung im Falle eines durch SQL verursachten Fehlers als zum Scheitern verurteilt zu betrachten. Das Wiederholen des Vorgangs kann nur auf der Ebene durchgeführt werden, auf der die Transaktion definiert ist (durch Neuerstellen dieser Transaktion und ihrer Verbindung).
Wenn Sie also einen fehlgeschlagenen Vorgang wiederholen, stellen Sie sicher, dass Sie eine vollständig neue Verbindung öffnen und eine neue Transaktion starten.
quelle
Hier ist eine C # 6-Methode zum Erkennen von Deadlocks.
Stellen Sie sicher, dass dieser try..catch Ihre gesamte Transaktion umgibt. Laut @Steven (Einzelheiten finden Sie in seiner Antwort) wird die Transaktion zurückgesetzt, wenn der Befehl sql aufgrund des Deadlocks fehlschlägt. Wenn Sie die Transaktion nicht neu erstellen, wird Ihr Wiederholungsversuch außerhalb des Kontexts von ausgeführt die Transaktion und kann zu Dateninkonsistenzen führen.
quelle