Der SQL Developer setzt implizite automatische COMMITs. Dieses COMMIT wird in folgenden Situationen unbewusst und automatisch abgesetzt.
(1) SQL Developer wird normal beendet, ohne COMMIT oder ROLLBACK Anweisung. In diesem Fall wird ein COMMIT abgesendet bevor das Programm beendet wird. Dies geschieht allerdings nicht bei einem Systemausfall des PCs oder einer nicht normalen Beendigung von SQL Developer. Hier erfolgt ein ROLLBACK.
(2) Das Absetzen einer DDL (Data Definition Language) Anweisung führt ebenso zu einem automatischen COMMIT. DDL Anweisungen sind zum Beispiel CREATE, DROP, ALTER, TRUNCATE, COMMENT und RENAME
(3) Ein Absetzen einer DCL (Data Control Language) Anweisung führt zu einem automatischen COMMIT. DCL Anweisungen sind unter anderem GRANT und REVOKE.
COMMIT VS ROLLBACK
Ein COMMIT speichert die Datenänderungen in die Datenbank, sodass der Zustand der vorherigen Daten überschrieben wird. Ab diesem Zeitpunkt können alle Benutzer die Ergebnisse sehen. Zudem wird die Sperre der betroffenen Zellen aufgehoben. Dies ist im Einklang mit „Nur Schreibvorgänge warten Schreibvorgänge ab“ (siehe Lesekonsistenz). Zusätzlich werden alle SAVEPOINTS gelöscht.
Ein ROLLBACK hingegen verwirft alle noch nicht gespeicherten Änderungen, wodurch der vorherige Zustand mit Hilfe vom UNDO-Tablespace hergestellt wird. Zudem werden die betroffenen gesperrten Zeilen wieder freigegeben.
Sollten einzelne DML (Data Manipulation Language) Anweisungen fehlschlagen, so wird nur diese Anweisung zurückgerollt. Dies geschieht mit einem impliziten SAVEPOINT. So wird ein INSERT in etwa folgendermaßen umgesetzt.
(1) SAVEPOINT before_insert;
(2) INSERT INTO <schema>.<table> VALUES (…)
(3a) kein Fehler: RELEASE SAVEPOINT (nur in MySQL möglich).
(3b) Fehler: ROLLBACK TO SAVEPOINT before_insert;
SAVEPOINT
Ein SAVEPOINT kann nur mit einem COMMIT oder ROLLBACK in ORACLE freigegeben werden. Ansonsten bleibt der SAVEPOINT bestehen. SAVEPOINTS können überschrieben werden, indem einfach nochmals der gleiche SAVEPOINT erstellt wird.
SAVEPOINT name;
Die Lesekonsistenz sorgt für eine ständige konsistente Datensicht. Dabei gelten nachfolgende Regeln:
– Schreibvorgänge warten Schreibvorgänge ab
– Lesevorgänge warten keine Schreibvorgänge ab. Gesperrte Zellen werden aus dem UNDO Tablespace übernommen
– Schreibvorgänge warten keine Lesevorgänge ab.
– Lesevorgänge warten ebenso keine Lesevorgänge ab.
FOR UPDATE
Eine weitere Möglichkeit ist die betroffenen Zellen vorab zu sperren. Dies geschieht mit der FOR UPDATE Anweisung. Sollten die betroffenen Zellen bereits durch einen anderen Nutzer gesperrt sein, so wartete die Datenbank mit der Ausführung des SELECT Statements ab. Die Sperre kann nur durch ein COMMIT oder ROLLBACK aufgehoben werden.
Ein Beispiel:
SELECT emp_name FROM emp WHERE empno = 12345 FOR UPDATE;
Die FOR UPDATE Anweisung sperrt alle betroffenen Zeilen von ein oder mehreren Tabellen. Spezieller kann ein FOR UPDATE OF <column name> sein, welches nur den betroffenen Wert der Spalten sperrt. Dadurch können andere Tabellen (z.B. welche durch JOINS benötigt werden, aber nicht geupdated werden) für andere Nutzer unversperrt gelassen werden.
SELECT emp_name FROM emp JOIN dept USING (deptid) WHERE deptname = 'xyz' FOR UPDATE of emp_name;
Das obere Beispiel sperrt somit nicht die Tabelle debt. Auch in der Tabelle emp sind alle anderen Felder nicht gesperrt und können aktualisiert werden. Getestet werden kann dies durch autonome Transaktionen:
PRAGMA AUTONOMOUS_TRANSACTION;