to interesujące pytanie!
Gdy Oracle napotka błąd, wycofa bieżące oświadczenie , a nie transakcję. Instrukcja jest instrukcją najwyższego poziomu, może to być instrukcja SQL (INSERT, UPDATE ...) lub blok PL/SQL.
Oznacza to, że gdy instrukcja (na przykład procedura pl/sql wywoływana z języka Java) zwróci błąd, Oracle umieści transakcję w tym samym stanie logicznym, co przed wywołaniem. Jest to niezmiernie pomocne, nie musisz się martwić o wykonane w połowie procedury (**).
This thread on AskTom covers the same topic:
[pismo] albo całkowicie się dzieje lub jej całkowicie nie zdarza i sposób że działa to baza danych ma logiczny odpowiednik:
begin
savepoint foo;
<<your statement>>
exception
when others then rollback to foo;
RAISE;
end;
This funkcja, moim zdaniem, dlatego jest o wiele łatwiejsze do napisania kodu bazy danych (*) w pl/sql niż w jakimkolwiek innym języku.
(*) kod, który współdziała z bazą Oracle oczywiście, przypuszczam, że rodzime języki proceduralne innych DBMS mają podobne funkcje.
(**) Dotyczy to wyłącznie DML od DDL are not transactional w Oracle. Należy również zachować ostrożność w przypadku niektórych pakietów DBMS, które aktualizują słownik danych (takich jak DBMS_STATS
), często dokonują zmian podobnych do DDL i zatwierdzają wydania. Jeśli masz wątpliwości, zapoznaj się z documentation.
Aktualizacja: to zachowanie jest jednym z najważniejszych koncepcji w PL/SQL, ja dostarczy mały przykład w celu wykazania niepodzielność z PL/SQL:
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 wycofał transakcję do punktu tuż przed wywołaniem p1. Nie ma pół-pracy. To tak, jakby procedura p1 nigdy nie została wywołana.
Właściwie to brzmi jak bardzo interesujące pytanie do mnie. Postgres wycofuje się przy błędzie i często uważałem to za denerwujące (i zastanawiałem się, czy Oracle zrobił coś podobnego). – jsight
Powiedz, dlaczego korzystasz z transakcji, jeśli nie chcesz wycofywać błędów? Jest to jeden z głównych celów transakcji. –
@Oliver: Niekoniecznie chcę lub nie chcę ich. Chcę tylko wiedzieć, jak działają. –