dit is een interessante vraag!
Wanneer Oracle een fout tegenkomt, zal het de huidige instructie terugdraaien , niet de transactie. Een instructie is elke instructie op het hoogste niveau, het kan een SQL-instructie (INSERT, UPDATE...) of een PL/SQL-blok zijn.
Dit betekent dat wanneer een instructie (bijvoorbeeld een pl/sql-procedure aangeroepen vanuit java) een fout retourneert, Oracle de transactie in dezelfde logische status zal plaatsen als vóór de aanroep. Dit is enorm handig, u hoeft zich geen zorgen te maken over half uitgevoerde procedures (**).
Deze thread op AskTom behandelt hetzelfde onderwerp:
[de verklaring] gebeurt VOLLEDIG of VOLLEDIG NIET en de manier waarop dat werkt, is dat de database het logische equivalent doet van:
begin
savepoint foo;
<<your statement>>
exception
when others then rollback to foo;
RAISE;
end;
Deze functie is naar mijn mening de reden waarom het een stuk eenvoudiger is om databasecode (*) in pl/sql te schrijven dan in welke andere taal dan ook.
(*) code die interageert met een Oracle DB natuurlijk, ik veronderstel dat de native proceduretalen van de andere DBMS vergelijkbare kenmerken hebben.
(**) Dit betreft alleen DML aangezien DDL niet transactioneel is in Oracle. Wees ook voorzichtig met sommige DBMS-pakketten die de datadictionary bijwerken (zoals DBMS_STATS
), doen ze vaak DDL-achtige wijzigingen en geven ze commits uit. Raadpleeg de documentatie in geval van twijfel.
Bijwerken: dit gedrag is een van de belangrijkste concepten in PL/SQL, ik zal een klein voorbeeld geven om de atomiciteit van de pl/sql-statements aan te tonen :
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 heeft de transactie teruggedraaid tot het punt net voordat p1 werd aangeroepen. Er is geen half werk gedaan. Het is alsof de procedure p1 nooit is aangeroepen.