Tại sao tôi không cần CAM KẾT kích hoạt cơ sở dữ liệu?


7

Chúng tôi không thể CAM KẾT / ROLLBACK trong trình kích hoạt DML vì giao dịch được xử lý thủ công sau câu lệnh DML. Tuy nhiên, kích hoạt cơ sở dữ liệu dường như là một ngoại lệ. Ví dụ: giả sử có một trình kích hoạt cơ sở dữ liệu:

CREATE OR REPLACE TRIGGER user_login_as
  AFTER LOGON 
    ON SCHEMA
BEGIN
  INSERT INTO user_login_log(username, log_date, action) VALUES (user, sysdate, 'User has logged in');
END user_login_as;

Trình kích hoạt không chứa thủ tục giao dịch tự động với cam kết bên trong đó, vậy ai là người cam kết chèn? Triggger này hoạt động như một lá bùa và chèn bản ghi mới vào bảng nhật ký sau khi người dùng đăng nhập. Nó có mùi giống như chức năng của Oracle ẩn và tôi không thể tìm thấy bất kỳ tài liệu tham khảo nào trong tài liệu của Oracle về điều đó. Tôi đang sử dụng Oracle11g.


Xin lỗi @NickChammas, có nghĩa là giữ nguyên câu trả lời của bạn, nhấp quá nhanh.
Aaron Bertrand

Câu trả lời:


13

Bạn nhận được một bối cảnh giao dịch tự động cho các kích hoạt này tự động.

Từ các CREATE TRIGGERtài liệu:

Một hoặc nhiều trạng thái cụ thể của cơ sở dữ liệu có thể gây ra kích hoạt. Bạn có thể tạo các kích hoạt cho các sự kiện này trên DATABASE hoặc SCHema trừ khi có ghi chú khác. Đối với mỗi sự kiện kích hoạt này, cơ sở dữ liệu sẽ mở ra một phạm vi giao dịch tự trị , kích hoạt trình kích hoạt và thực hiện bất kỳ giao dịch riêng biệt nào (bất kể giao dịch người dùng hiện có).

Điều gì xảy ra nếu kích hoạt thất bại phụ thuộc vào kích hoạt / sự kiện chính xác. Xem Xử lý ngoại lệ trong Triggers . Cụ thể, một trình kích hoạt đăng nhập không thành công với một ngoại lệ rất có thể khóa những người dùng không phải là dba - ngoại lệ làm cho việc đăng nhập thất bại trừ khi người dùng có các đặc quyền cụ thể.


Thật thú vị những gì xảy ra nếu có một ngoại lệ trong cơ thể kích hoạt. Tôi giả sử Oracle thực hiện rollback "im lặng" trong trường hợp đó?
Centurion

Chỉnh sửa với một chút thông tin cho điều đó.
Mat

-1
CREATE OR REPLACE TRIGGER t_trigger
AFTER INSERT ON t1 FOR EACH ROW

DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
 i PLS_INTEGER; 
BEGIN
  SELECT COUNT(*)
  INTO i
  FROM t1;

  INSERT INTO t2
  VALUES
  (i);
  COMMIT;
END;
/

3
Bạn có thể vui lòng giải thích những gì nó nói với chúng tôi?
dezso

-1

Một cam kết bên trong một trình kích hoạt sẽ đánh bại định nghĩa cơ bản của giao dịch nguyên tử (xem ACID). Theo định nghĩa logic kích hoạt là một phần mở rộng của hoạt động DML gốc. Do đó, những thay đổi được thực hiện trong các kích hoạt nên được cam kết hoặc khôi phục như một phần của giao dịch mà chúng thực hiện. Vì lý do này, các trình kích hoạt KHÔNG được phép thực thi các câu lệnh CAMIT hoặc ROLLBACK (ngoại trừ các trình kích hoạt tự trị). Dưới đây là một ví dụ về những gì sẽ xảy ra khi họ làm:

SQL> CREATE TABLE tab1 (col1 NUMBER);
Table created.

SQL> CREATE TABLE log (timestamp DATE, operation VARCHAR2(2000));
Table created.

SQL> CREATE TRIGGER tab1_trig
  2     AFTER insert ON tab1
  3  BEGIN
  4     INSERT INTO log VALUES (SYSDATE, 'Insert on TAB1');
  5     COMMIT;
  6  END;
  7  /
Trigger created.

SQL> INSERT INTO tab1 VALUES (1);
INSERT INTO tab1 VALUES (1)
            *
ERROR at line 1:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SCOTT.TAB1_TRIG", line 3
ORA-04088: error during execution of trigger 'SCOTT.TAB1_TRIG'

Giao dịch tự trị:

Như cách giải quyết, người ta có thể sử dụng các giao dịch tự trị. Giao dịch tự động thực hiện tách biệt với giao dịch hiện tại.

Không giống như các trình kích hoạt thông thường, các trình kích hoạt tự động có thể chứa các câu lệnh CAMIT và ROLLBACK. Thí dụ:

SQL> CREATE OR REPLACE TRIGGER tab1_trig
  2    AFTER insert ON tab1
  3  DECLARE
  4    PRAGMA AUTONOMOUS_TRANSACTION;
  5  BEGIN
  6    INSERT INTO log VALUES (SYSDATE, 'Insert on TAB1');
  7    COMMIT; -- only allowed in autonomous triggers
  8  END;
  9  /
Trigger created.

SQL> INSERT INTO tab1 VALUES (1);
1 row created.

Lưu ý rằng với ví dụ trên sẽ chèn và cam kết các mục nhật ký - ngay cả khi giao dịch chính được khôi phục!

Hãy nhớ rằng một thủ tục / hàm / trình kích hoạt "autonomous_transaction" là toàn bộ giao dịch và do đó, nó phải kết thúc bằng một câu lệnh cam kết hoặc quay lại.


1
Điều này không thực sự trả lời câu hỏi - OP hiểu rõ lý do tại sao họ không cần logic giao dịch trong các kích hoạt DML. Câu hỏi là về kích hoạt cơ sở dữ liệu, mà câu trả lời được đăng và chấp nhận quan tâm.
RDFozz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.