Ich habe eine Insert
gespeicherte Prozedur, die Daten in die zweite gespeicherte Prozedur einspeist Table1
und den Column1
Wert von Table1
dieser abruft und die zweite gespeicherte Prozedur aufruft, die die Tabelle 2 speist.
Aber wenn ich die zweite gespeicherte Prozedur aufrufe als:
Exec USPStoredProcName
Ich erhalte folgende Fehlermeldung:
Die Transaktionsanzahl nach EXECUTE zeigt eine nicht übereinstimmende Anzahl von BEGIN- und COMMIT-Anweisungen an. Vorherige Zählung = 1, aktuelle Zählung = 0.
Ich habe die Antworten in anderen solchen Fragen gelesen und kann nicht feststellen, wo genau die Anzahl der Festschreibungen durcheinander gebracht wird.
sql
sql-server-2012
sqlexception
Vignesh Kumar A.
quelle
quelle
Antworten:
Wenn Sie einen TRY / CATCH-Block haben, ist die wahrscheinliche Ursache, dass Sie eine Transaktionsabbruchausnahme abfangen und fortfahren. Im CATCH-Block müssen Sie immer die
XACT_STATE()
entsprechenden abgebrochenen und nicht festgeschriebenen (zum Scheitern verurteilten) Transaktionen überprüfen und verarbeiten. Wenn Ihr Anrufer eine Transaktion startet und der Calee beispielsweise auf einen Deadlock stößt (der die Transaktion abgebrochen hat), wie wird der Angerufene dem Anrufer mitteilen, dass die Transaktion abgebrochen wurde und nicht mit "Business as usual" fortfahren sollte? Der einzig mögliche Weg besteht darin, eine Ausnahme erneut auszulösen und den Anrufer zu zwingen, mit der Situation umzugehen. Wenn Sie eine abgebrochene Transaktion stillschweigend verschlucken und der Anrufer weiterhin davon ausgeht, dass sie sich noch in der ursprünglichen Transaktion befindet, kann nur Chaos sicherstellen (und der Fehler, den Sie erhalten, ist die Art und Weise, wie die Engine versucht, sich selbst zu schützen).Ich empfehle Ihnen, die Ausnahmebehandlung und verschachtelte Transaktionen zu überprüfen, die ein Muster anzeigt, das mit verschachtelten Transaktionen und Ausnahmen verwendet werden kann:
quelle
xact_abort on
?if @xstate = -1 rollback;
Bei diesem Blick MSDN Beispiel , sollten wir nicht die vollständige Transaktion Rollback , es sei denn es gab nicht eine äußere Transaktion (das heißt, es sei denn , wir habenbegin tran
). Ich denke, das Verfahren sollte nur durchgeführt werden,rollback
wenn wir die Transaktion gestartet haben, wodurch das Problem von @ sparrow behoben würde.Ich hatte auch dieses Problem. Für mich war der Grund, dass ich es tat
anstatt
in einer gespeicherten Prozedur.
quelle
Dies geschieht normalerweise, wenn die Transaktion gestartet wird und entweder nicht festgeschrieben oder nicht zurückgesetzt wird.
Falls der Fehler in Ihrer gespeicherten Prozedur auftritt, kann dies die Datenbanktabellen sperren, da die Transaktion aufgrund einiger Laufzeitfehler ohne Ausnahmebehandlung nicht abgeschlossen wird. Sie können die Ausnahmebehandlung wie unten verwenden. SET XACT_ABORT
Quelle
quelle
Beachten Sie, dass bei Verwendung verschachtelter Transaktionen bei einer ROLLBACK-Operation alle verschachtelten Transaktionen zurückgesetzt werden, einschließlich der äußersten.
Dies kann bei Verwendung in Kombination mit TRY / CATCH zu dem von Ihnen beschriebenen Fehler führen. Sehen Sie hier mehr .
quelle
Dies kann auch auftreten, wenn Ihre gespeicherte Prozedur nach dem Öffnen einer Transaktion auf einen Kompilierungsfehler stößt (z. B. Tabelle nicht gefunden, ungültiger Spaltenname).
Ich stellte fest, dass ich 2 gespeicherte Prozeduren verwenden musste, eine "Worker" -Prozedur und eine Wrapper-Prozedur mit Try / Catch, beide mit einer Logik ähnlich der von Remus Rusanu beschriebenen. Der Worker-Catch wird verwendet, um die "normalen" Fehler zu behandeln, und der Wrapper-Catch, um Kompilierungsfehler zu behandeln.
https://msdn.microsoft.com/en-us/library/ms175976.aspx
Fehler, die von einem TRY… CATCH-Konstrukt nicht betroffen sind
Hoffentlich hilft dies jemand anderem, ein paar Stunden Debugging zu sparen ...
quelle
In meinem Fall wurde der Fehler durch ein
RETURN
innerhalb desBEGIN TRANSACTION
. Also hatte ich so etwas:und es muss sein:
quelle
Für mich war das Update nach ausgiebigem Debuggen ein einfacher fehlender Wurf; Anweisung im Fang nach dem Rollback. Ohne sie ist diese hässliche Fehlermeldung das, was Sie am Ende haben.
quelle
Ich hatte die gleiche Fehlermeldung, mein Fehler war, dass ich am Ende der Zeile COMMIT TRANSACTION ein Semikolon hatte
quelle
Ich bin einmal auf diesen Fehler gestoßen, nachdem ich diese Anweisung aus meiner Transaktion weggelassen habe.
quelle
Stellen Sie sicher, dass Sie nicht mehrere Transaktionen in derselben Prozedur / Abfrage haben, von denen eine oder mehrere nicht festgeschrieben sind.
In meinem Fall hatte ich versehentlich eine BEGIN TRAN-Anweisung in der Abfrage
quelle
Dies kann auch davon abhängen, wie Sie den SP über Ihren C # -Code aufrufen. Wenn der SP einen Tabellentypwert zurückgibt, rufen Sie den SP mit ExecuteStoreQuery auf, und wenn der SP keinen Wert zurückgibt, rufen Sie den SP mit ExecuteStoreCommand auf
quelle
Vermeide das Benutzen
Anweisung, wenn Sie verwenden
und
Anweisungen in gespeicherten SQL-Prozeduren
quelle
Meiner Meinung nach ist die akzeptierte Antwort in den meisten Fällen ein Overkill.
Die Fehlerursache ist häufig eine Nichtübereinstimmung von BEGIN und COMMIT, wie durch den Fehler deutlich angegeben. Dies bedeutet:
anstatt
Das Weglassen der Transaktion nach dem Start führt zu diesem Fehler!
quelle
Wenn Sie eine Codestruktur haben, die Folgendes umfasst:
Dann benutze:
quelle