sql >> Databasteknik >  >> RDS >> Oracle

Återställer Oracle transaktionen vid ett fel?

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.



  1. Skapa ny användare i MySQL och ge den full tillgång till en databas

  2. Hur man kan förutse och undkomma enstaka citat ' i oracle

  3. Oracle Database BLOB till InputStream i Java?

  4. SQL Join på null-värden