detta är en intressant fråga!
När Oracle stöter på ett fel kommer det att återställa det aktuella påståendet , inte transaktionen. En sats är vilken som helst instruktion på toppnivå, den kan vara en SQL-sats (INSERT, UPDATE...) eller ett PL/SQL-block.
Det betyder att när en sats (till exempel en pl/sql-procedur anropad från java) returnerar ett fel kommer Oracle att sätta transaktionen i samma logiska tillstånd som före anropet. Detta är oerhört användbart, du behöver inte oroa dig för halvkörda procedurer (**).
Den här tråden på AskTom tar upp samma ämne:
[påståendet] antingen händer det HELT eller så händer det INTE och det sätt som fungerar är att databasen gör den logiska motsvarigheten till:
begin
savepoint foo;
<<your statement>>
exception
when others then rollback to foo;
RAISE;
end;
Denna funktion, enligt min mening, är därför det är mycket lättare att skriva databaskod (*) i pl/sql än på något annat språk.
(*) kod som interagerar med en Oracle DB så klart, jag antar att de inhemska procedurspråken i de andra DBMS har liknande funktioner.
(**) Detta gäller endast DML eftersom DDL inte är transaktionsbaserade i Oracle. Var också försiktig med vissa DBMS-paket som uppdaterar dataordlistan (som DBMS_STATS
), gör de ofta DDL-liknande ändringar och utfärdar commits. Se dokumentationen vid tveksamhet.
Uppdatering: detta beteende är ett av de viktigaste koncepten i PL/SQL, jag kommer att ge ett litet exempel för att visa atomiciteten i pl/sql-satserna :
SQL> CREATE TABLE T (a NUMBER);
Table created
SQL> CREATE OR REPLACE PROCEDURE p1 AS
2 BEGIN
3 -- this statement is successful
4 INSERT INTO t VALUES (2);
5 -- this statement will raise an error
6 raise_application_error(-20001, 'foo');
7 END p1;
8 /
Procedure created
SQL> INSERT INTO t VALUES (1);
1 row inserted
SQL> EXEC p1;
begin p1; end;
ORA-20001: foo
ORA-06512: at "VNZ.P1", line 5
ORA-06512: at line 2
SQL> SELECT * FROM t;
A
----------
1
Oracle har rullat tillbaka transaktionen till punkten precis innan anropet p1. Det finns inget halvarbete gjort. Det är som om proceduren p1 aldrig hade anropats.