đây là một câu hỏi thú vị!
Khi Oracle gặp lỗi, nó sẽ khôi phục câu lệnh hiện tại, chứ không phải giao dịch. Một câu lệnh là bất kỳ lệnh mức 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ụ một thủ tục pl/sql được gọi từ java) trả về một lỗi, Oracle sẽ đặt giao dịch ở trạng thái logic giống như trước cuộc 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 hiện một nửa (**).
This thread on AskTom covers the same topic:
[tuyên bố] hoặc HOÀN TOÀN xảy ra hoặc nó HOÀN TOÀN KHÔNG xảy ra và cách mà làm việc là cơ sở dữ liệu không tương đương logic của:
begin
savepoint foo;
<<your statement>>
exception
when others then rollback to foo;
RAISE;
end;
này tính năng, theo ý kiến của tôi, là lý do tại sao nó dễ dàng hơn nhiều để viết mã cơ sở dữ liệu (*) bằng pl/sql hơn bất kỳ ngôn ngữ nào khác.
(*) mã tương tác với một DB Oracle tất nhiên, tôi cho rằng ngôn ngữ thủ tục gốc của các DBMS khác có các tính năng tương tự.
(**) Điều này chỉ liên quan đến DML kể từ DDL are not transactional trong Oracle. Hãy 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
), chúng thường thực hiện các thay đổi giống như DDL và phát hành các cam kết. Tham khảo documentation 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 số nguyên tử của các báo cáo 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 có cuộn lại giao dịch đến đ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.
Thực ra, nó giống như một câu hỏi rất thú vị đối với tôi. Postgres rollback về lỗi, và tôi thường thấy nó khó chịu (và tự hỏi nếu Oracle đã làm một cái gì đó tương tự). – jsight
Hãy cho tôi biết, tại sao bạn sử dụng giao dịch nếu bạn không muốn khôi phục lỗi? Đây là một trong những mục đích chính của giao dịch. –
@Oliver: Tôi không nhất thiết muốn hoặc không muốn chúng. Tôi chỉ muốn biết cách họ làm việc. –