đây là một câu hỏi thú vị!
Khi Oracle gặp lỗi, nó sẽ khôi phục lại câu lệnh hiện tại , không phải giao dịch. Một câu lệnh là bất kỳ lệnh cấp cao nhất nào, nó có thể là một câu lệnh SQL (INSERT, UPDATE ...) hoặc một khối PL / SQL.
Điều này có nghĩa là khi một câu lệnh (ví dụ:thủ tục pl / sql được gọi từ java) trả về lỗi, Oracle sẽ đặt giao dịch ở trạng thái logic giống như trước khi gọi. Điều này vô cùng hữu ích, bạn không phải lo lắng về các thủ tục được thực thi nửa chừng (**).
Chủ đề này trên AskTom bao gồm cùng một chủ đề:
[câu lệnh] HOÀN TOÀN KHÔNG xảy ra hoặc HOÀN TOÀN KHÔNG xảy ra và cách hoạt động là cơ sở dữ liệu thực hiện tương đương lôgic của:
begin
savepoint foo;
<<your statement>>
exception
when others then rollback to foo;
RAISE;
end;
Tính năng này, theo ý kiến của tôi, là lý do tại sao viết mã cơ sở dữ liệu (*) bằng pl / sql dễ dàng hơn nhiều so với bất kỳ ngôn ngữ nào khác.
(*) tất nhiên mã tương tác với Oracle DB, tôi cho rằng các ngôn ngữ thủ tục gốc của DBMS khác có các tính năng tương tự.
(**) Điều này chỉ liên quan đến DML vì DDL không phải là giao dịch trong Oracle. Cũng nên cẩn thận với một số gói DBMS cập nhật từ điển dữ liệu (chẳng hạn như DBMS_STATS
), họ thường thực hiện các thay đổi giống như DDL và đưa ra các cam kết. Tham khảo tài liệu trong trường hợp nghi ngờ.
Cập nhật: hành vi này là một trong những khái niệm quan trọng nhất trong PL / SQL, tôi sẽ cung cấp một ví dụ nhỏ để chứng minh tính nguyên tử của các câu lệnh 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 đã khôi phục giao dịch về điểm ngay trước khi gọi p1. Không có một nửa công việc được thực hiện. Nó như thể thủ tục p1 chưa bao giờ được gọi.