sql >> Database >  >> RDS >> Oracle

Draait Oracle de transactie terug bij een fout?

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.



  1. Hoe kan ik in de kortst mogelijke tijd 10 miljoen records invoegen?

  2. RAC-volgordeconflict

  3. Databasemail inschakelen in SQL Server (T-SQL)

  4. Moet de tijdzone van MySQL worden ingesteld op UTC?