SQL: Rollback Transaction funzt nicht
Chrissicom 14.06.2008 - 05:00 4202 5
Chrissicom
Rise of the Ryzen
|
BEGIN TRANSACTION CreateEmployee
INSERT INTO Employee(LoginID,Title,Gender,....)
VALUES (@LoginID,@Title,@Gender,....)
INSERT INTO BankAccount (BankName,KTONR,BLZ,IBAN,BIC)
VALUES (@BankName,@KTONR,@BLZ,@IBAN,@BIC)
INSERT INTO BankAccountEmployee (EmployeeID,AccountID)
VALUES ((SELECT max(EmployeeID) FROM Employee),(SELECT max(AccountID) FROM BankAccount))
ROLLBACK TRANSACTION CreateEmployee
COMMIT TRANSACTION CreateEmployee
GO
Das ist eine Stored Procedure, allerdings meckert er an der ROLLBACK, COMMIT Syntax rum und ich verstehe nicht wieso. Im SQL Manager sagt er erstmal nix und lasst mich eine Stored Procedure mit dem Code erzeugen. Wenn ich das ganze von der Anwendung aber ausführen möchte und die Daten eintrage sagt er das die Commit Transaction Klausel keine corresponding Begin Transaction Klausel hat, aber das is doch blödsinn. Ich schreibe doch am Anfang BEGIN, und vorm Commit nen Rollback falls Fehler auftreten damit gar nix eingefügt wird und dann das Commit wieso findet er da die Begin Transaction Klausel nimmer? Wenn ich das Rollback wegmache geht's aber dann können halt unfertige Datensätze in der Datenbank landen was ich nich will. Also wo is der Fehler???
Bearbeitet von Chrissicom am 14.06.2008, 11:56 (code tag added)
|
that
ModeratorHoffnungsloser Optimist
|
Eine Transaktion hat einen Anfang (BEGIN) und ein Ende (ROLLBACK *oder* COMMIT). Du hast eine Transaktion, die du mit ROLLBACK beendest, und dann ein überflüssiges COMMIT. (ein ROLLBACK ohne irgendeiner Bedingung am Ende ist allerdings wenig zweckmäßig, wenn du jemals irgendwelche Daten in die Datenbank füllen willst )
Bearbeitet von that am 14.06.2008, 10:40
|
Chrissicom
Rise of the Ryzen
|
Hmmm, also in den Beispielen auf MSDN steht aber wenn ich das nicht völlig falsch verstanden hab, das ein ROLLBACK in T-SQL zwischen BEGIN und COMMIT zu stehen hat. Wenn ich nur das ROLLBACK da hinschreibe ohne Bedingung, dann setzt er die Aktion wie du schon richtig feststellst immer zurück. Ich werde mal probieren sowas wie IF EXCEPTION != NULL davor zu setzen und poste dann hier rein wenn es so gehen sollte.
Was übrigens m.E. funktioniert:
BEGIN TRY BEGIN TRAN T1 // ... COMMIT TRAN T1 END TRY BEGIN CATCH ROLLBACK TRAN T1 END CATCH GO
Also wie so ein schöner Try and Catch Block in C# oder Java. Das Problem dabei ist allerdings das er keinen Exception Code zurück gibt in diesem Fall , sondern nur das Rollback ausführt und somit das Error Handling das ich im Code Behind File programmiert habe nicht greift und nur eine "kann nicht eingefügt werden Meldung" anstatt des tatsächlichen Fehlers zurück gegeben wird.
Bearbeitet von Chrissicom am 14.06.2008, 11:27
|
semteX
begehrt die rostschaufel
|
du führst alles aus und machst danach ein rollback....
hmm
wieso führt er nur jedes mal ein rollback aus?
natürlich musst du das rollback an ne bedingung hängen, exception oder selbst mit count oder ähnlichem nachkontrolliern.
und wie that schon sagte => was soll das commit noch commiten? die transaktion wurde doch mim rollback schon zerstört
es gibt so viele gute links zum thema pl/sql + transactions + exceptions, so schwer is das ned
|
Chrissicom
Rise of the Ryzen
|
1. Benutze ich T-SQL und nicht PL/SQL 2. Habe ich ja nun schon eine Lösung gefunden wie das mit dem Rollback funzt Wenn du dir das MSDN Beispiel anschaust für ROLLBACK dann steht das dort ohne Bedingung zwischen BEGIN und COMMIT. Da muss wohl für mich nicht ersichtlich im Text irgendwo stehen das man noch eine Bedingung braucht. Jedenfalls ist das verbleibende Problem jetzt noch, das durch das Rollback die Exception Message die von der Transaktion eigentlich generiert werden würde "zerstört" wird. Das will ich aber vermeiden damit ich im C# Code über e.Exception.Message (e ist vom Typ object) den Fehler auslesen kann damit ich dem Benutzer eine Nachricht über den genauen Fehler geben kann, anstatt einfach nur die plumpe Aussage "hat nicht geklappt". Feedback.Text = "Es konnte leider keine Änderung vorgenommen werden. Setz dich bitte mit dem Administrator in Verbindung." + " (" + DateTime.Now + ")";
if (e.Exception != null) /* We want to avoid showing Server Error Pages to the user so we output the error text to a label */
{
Feedback.Text = e.Exception.Message;
e.ExceptionHandled = true;
}
break;
Durch das Rollback bleibt e.Exception eben null, das will ich aber nicht wenns nicht zum COMMIT kommt. Ein simples PRINT @@ERROR im Catch Block bringt leider nix.
|
Triple-X
Addicted
|
Bearbeitet von Triple-X am 16.06.2008, 13:48
|