2011-09-19 111 views
4

我遇到了一個有趣的情況,用autonomous_transaction進行實驗。考慮以下情況(請注意,它不打算這樣寫:概念恰恰證明):觸發和約束衝突中的autonomous_transaction

create table t 
(
id int primary key, 
changed date 
) 
/

create or replace trigger t_trig 
before insert or update 
on t 
for each row 
declare 
    PRAGMA AUTONOMOUS_TRANSACTION; 
begin 
    :new.changed := sysdate; 
    commit; 
end; 
/

insert into t(id, changed) values (1, sysdate); 
insert into t(id, changed) values (2, sysdate); 

更改的日期的當前時間:

SQL> select * from t; 

     ID CHANGED 
--------- ----------------- 
     1 19.09.11 15:29:44 
     2 19.09.11 15:32:35 

讓我們5秒打破然後執行以下操作:

update t set id = 2 where id = 1; 

很顯然,這將失敗,違反約束,但它不會改變changed屬性,以及:

SQL> select * from t; 

     ID CHANGED 
--------- ----------------- 
     1 19.09.11 15:29:44 
     2 19.09.11 15:32:35 

我的問題是:爲什麼會發生這種情況?我確信我誤解了一些基本概念,但我無法理解。

在此先感謝您的幫助。

回答

1

PRAGMA AUTONOMOUS TRANSACTION保存上下文,打開另一個會話並創建一些內容。提交是必須的,否則這些更改將會丟失。您可以理解,只有在數據庫中的某些塊中所做的更改在此會話中才有意義(自治)。

所以,在你的觸發器中,你什麼都不做。 如果我們可以在這種模式下說出這個變量,:new.changed將在另一個會話中「更改」。它不會因您的更新而改變。