Ich beginne eine Transaktion und mache dann ein erfolgreiches “Insert”, dann mache ich noch ein Insert (welches absichtlich einen Fehler verursacht), das führt dazu, dass automatisch meine Transaktion zurückgesetzt wird (rollback), es ist also auch der erste insert nicht mehr durchgeführt worden.
Jetzt meine Frage, kann ich dieses Verhalten abschalten, also, dass es kein “auto-rollback” bei einem Fehler gibt, sondern die Transaktion bestehen bleibt?!
Das Verhalten ist zum Beispiel bei MySql und bei Oracle nicht so, dort kann ich die Transaktion, trotz Fehler, immer noch weiter nutzen.
Jetzt meine Frage, kann ich dieses Verhalten abschalten, also, dass es kein “auto-rollback” bei einem Fehler gibt, sondern die Transaktion bestehen bleibt?!
Nein.
Das Verhalten ist zum Beispiel bei MySql und bei Oracle nicht so, dort kann ich die Transaktion, trotz Fehler, immer noch weiter nutzen.
Dann ist das dort ein Fehler.
Vielen Dank schonmal für Antworten!
Wenn Du keine Transaktion willst, dann verwende keine. Oder verwende Savepoints.
Tatsache, zumindest bei MySQL geht das. Die Oracle auf dem anderen Rechner will ich jetzt nicht hochfahren.
Also, meine Meinung dazu: wenn es einen Fehler gab ist irgendetwas in der Transaktion schief gelaufen. Die Transaktion hat keine Berechtigung mehr weiter Daten anzunehmen.
Andere Datenbanken mögen das anders sehen. Wenn man sich vor Augen hält das PostgreSQL sehr viel Wert auf Datensicherheit legt dann ist die hier gewählte Vorgehensweise verständlich.
Dann ist MySQL kapott. Definitiv. Bei ORA bezweifle ich das aber heftigst.
Also, meine Meinung dazu: wenn es einen Fehler gab ist irgendetwas in der Transaktion schief gelaufen. Die Transaktion hat keine Berechtigung mehr weiter Daten anzunehmen.
Um das noch mal klarzustellen: Ein Transaktion hat das Ziel, eine oder mehrere Manipulationen am Datenbestand als eine atomare Aktion ablaufen zu lassen. Beispiel: Kontoüberweisung. Von Konto A auf Konto B. Der Betrag wird von A abgebucht, und dann auf Konto B zugebucht. Das ist eine Transaktion. Entweder beide Buchungen, oder keine. Erst bei A abbuchen, und dann feststellen, daß Konto B nicht existiert, und dennoch den Betrag bei A abzubuchen, kann nicht das Ziel sein. Alles oder nichts.
Und wenn Du 100 Datensätze einfügen willst und der 98. schlägt fehl,
dann verhindert eine Transaktion zuverlässig, daß die Daten nachher nur zu 99% korrekt sind. Die Transaktion als solche schlug fehl, es ist dann Aufgabe der Applikation, damit fertig zu werden. Wenn MySQL von sich aus bei sehr vielen Inserts ab und an mal ein COMMIT sich erträumt dann ist das schlicht ein Bug.
PS.: ich empfehle bei der Arbeit mit psql eine ~/.psqlrc mit u.a. dieser Zeile:
es ist naemlich durchaus sinnvoll insert-fehler (constraint-checks) in kauf zu nehmen - um zu ermitteln, ob fall a funktioniert - wenn nicht dann eben fall b … wenn der dann auch schief geht kann man die transaktion immernoch zuruecksetzen
waere das was du meinst richtig, haette man sich die funktion rollback sparen koennen … was meinst wozu es die gibt
Noch einmal für Dich: das ein Fehler in einer Transaktion diese ungültig werden läßt. Alles was vorher/nachher in dieser Transaktion passiert, ist daher ungültig. Dazu sind Transaktionen da. Um innerhalb einer Transaktion Fehler abfangen zu können, gibt es Savepoints.
Ab jetzt habe ich aber keine weitere Lust, Dir und anderen die Doku vorzulesen. EOD.
So seh ich das auch… Meine Frage hat ja eine heftige Diskussion hervorgerufen Es ist einfach so, dass ich hier programmtechnisch selbst entscheiden möchte, was passiert, wenn ein Fehler bei einer einzelnen SQL-Operation auftritt, ob ich dann zum Beispiel selbst ein komplettes Rollback mache oder doch weiter mache. Klar, dass wenn beim commit was schief läuft, muss natürlich die gesamte Transaktion rückgängig gemacht werden.
Aber mit Oracle ist es definitiv so:
sqlplus starten
Transaktion beginnen
insert machen (funktionierend)
noch einen insert machen (absichtlich fehlerhaft)
commit
Ergebnis: die Daten des ersten Inserts sind gespeichert.
Ja, dieses eine Beispiel tut auch ohne Transaktion…
Transaktion brauch ich aber trotzdem, weil ich dann im Programm entscheiden will, wann ich ein rollback mache und wann nicht !!! Und in der Regel sind da mehr Operationen als nur 1 beteiligt
AUTOCOMMIT When on (the default), each SQL command is automatically committed upon successful completion. To postpone commit in this mode, you must enter a BEGIN or START TRANSACTION SQL command. When off or unset, SQL commands are not committed until you explicitly issue COMMIT or END. The autocommit-off mode works by issuing an implicit BEGIN for you, just before any command that is not already in a transaction block and is not itself a BEGIN or other transaction-control command, nor a command that cannot be executed inside a transaction block (such as VACUUM).[INDENT]Note: In autocommit-off mode, you must explicitly abandon any failed transaction by entering ABORT or ROLLBACK. Also keep in mind that if you exit the session without committing, your work will be lost.
[/INDENT][INDENT]Note: The autocommit-on mode is PostgreSQL’s traditional behavior, but autocommit-off is closer to the SQL spec. If you prefer autocommit-off, you might wish to set it in the system-wide psqlrc file or your ~/.psqlrc file.
[/INDENT]das was ORA und co macht ist also selbst lt. des heiligen PG-Evangeliums standardischer als das standardigste aller standard-DBMS …
Wie man da lesen kann gibt es auch eine Möglichkeit bei PG das “gewohnte” (ich wuerde sagen - das RICHTIGE! g) Verhalten herzustellen.
du solltest aufhoeren immer gleich beleidigt zu sein, wenn irgendwer mal ein problem mit deinem lieblingsspielzeug hat
auch Postgres ist nur ein Mensch
@O.S …
probiert habe ich das ganze nicht - was die PG-Dokue bei dem Transaktionskram naemlich verschweigt, ist das AUTOCOMMIT auch ein AUTOROLLBACK zu beinhalten scheint …
also der connection ein SET AUTOCOMMIT OFF senden before du die TX so verwenden moechtest … es kann ja nicht schaden ein SET AUTOCOMMIT ON zu senden wenn die TX zuende ist - damit man danach wenigstens weiss was det gute PG so tut …
FEHLER: SET AUTOCOMMIT TO OFF wird nicht mehr unterstützt
********** Fehler **********
FEHLER: SET AUTOCOMMIT TO OFF wird nicht mehr unterstützt
SQL Status:0A000
Auweia - PG 8.3
die Option ist aber in der 8.3er Doku zu finden … hmm … dann kannst ja probieren das in diesem seltsamen config file zu aendern … dann gilt das aber wohl fuer die gesamte server instanz …
Mist… geht tatsächlich nicht, bekomme dieselbe Meldung…
In der Doku steht:
The server-side autocommit setting was removed and reimplemented in client applications and languages. Server-side autocommit was causing too many problems with languages and applications that wanted to control their own autocommit behavior, so autocommit was removed from the server and added to individual client APIs as appropriate.
Jetzt meine Frage, wie stell ich das über JDBC ein?
Ich forsche mit dir … wenn du was findest poste es hier - interessiert mich auch
schon erledigt:
java.sql.Connection c =…;
c.setAutoCommit(autoCommit)
als Kommantar (nicht jdoc) steht im PG-JdbcTreiber:
/*
If a connection is in auto-commit mode, than all its SQL
statements will be executed and committed as individual
transactions. Otherwise, its SQL statements are grouped
into transactions that are terminated by either commit()
or rollback(). By default, new connections are in auto-
commit mode. The commit occurs when the statement completes
or the next execute occurs, whichever comes first. In the
case of statements returning a ResultSet, the statement
completes when the last row of the ResultSet has been retrieved
or the ResultSet has been closed. In advanced cases, a single
statement may return multiple results as well as output parameter
values. Here the commit occurs when all results and output param
values have been retrieved.
@param autoCommit - true enables auto-commit; false disables it
@exception SQLException if a database access error occurs
*/
Das erklaert natuerlich uach das Ungültigwerden der TX bei den ganzen üblichen PG-clients …
weil die auch so arbeiten werden … immer wenn ein Fehler auftritt - bei irgendeinem Kommando in der TX machen die ein Rollback … dann ist die TX natuerlich hinueber …
aber das ist eben NICHT das klassische Verhalten wie man es von einer TX erwartet - sondern das Verhalten “üblicher” PG-clients …
akretschmer ist nicht beleidigt, er hat nur keine Lust, dir ständig aus der Dokumentation vorzulesen. Ok, auf Dauer ist so etwas schon ein Grund, genervt zu sein.
Noch mal für dich, zum Mitschreiben: PostgreSQL nimmt das Thema Datensicherheit sehr ernst. Daher wird jeder Fehler, der in einer Transaktion auftritt, auch als Problem für die Transaktion gewertet und diese darf damit nicht commited werden. Wenn eine Transaktion nicht committed werden kann - welchen Sinn macht es noch, weitere Befehle anzunehmen?
So, und jetzt denke du mal logisch nach, wieso SAVEPOINT und ROLLBACK TO SAVEPOINT funktionieren … selbst wenn es in einer Transaktion Fehler gab kann ich die Transaktion zu einem funktionierenden Punkt zurückrollen ohne den Rest der Änderungen zu verlieren. Würde PostgreSQL einfach so alles wegwerfen weil es einen Syntax-Fehler gab dann würden auch SAVEPOINTs nicht funktionieren. Wenn du das ausgeknobelt hast und deinen Ton anpasst können wir uns weiter unterhalten.
auch Postgres ist nur ein Mensch > >
Schwachsinn. Wir reden hier über meine Daten und nicht über Gefühle.
probiert habe ich das ganze nicht
Natürlich nicht, von dir lesen wir hier immer erst viel heiße Luft bevor du selbst auch nur einen Blick in irgendwelche Dokumtation wirfst.
BEGIN;
INSERT INTO tabelle (id, data) VALUES (1, 'abc');
SELECT id, data FROM tabelle;
SAVEPOINT sp1;
SELECT kaputt;
ROLLBACK TO SAVEPOINT sp1;
SELECT id, data FROM tabelle;
ROLBACK; oder COMMIT;