2013-08-26 18 views
6

我想知道如果我在oracle數據庫正在使用時更換觸發器,是否會丟失任何數據。我創造了一個玩具的例子,似乎我不會,但我的一個同事聲稱不然。如果我在應用程序運行時替換Oracle觸發器,我會錯過任何更改嗎?

create table test_trigger (id number); 
create table test_trigger_h (id number); 
create sequence test_trigger_seq; 

--/ 
create or replace trigger test_trigger_t after insert on test_trigger for each row 
begin 
    insert into test_trigger_h (id) values (:new.id); 
end;  
/

--/ 
begin 
    for i in 1..100000 loop 
    insert into test_trigger (id) values (test_trigger_seq.nextval); 
    end loop; 
end; 
/

--/ 
begin 
    for i in 1..10000 loop 
    execute immediate 'create or replace trigger test_trigger_t after insert on test_trigger for each row begin insert into test_trigger_h (id) values (:new.id); end;'; 
    end loop; 
end; 
/

ran the two loops at the same time 

select count(1) from test_trigger; 

COUNT(1) 
100000 

select count(1) from test_trigger_h; 

COUNT(1) 
100000 
+2

有趣。如果你分離了'drop'和'create'語句,我會希望事件被遺漏;但是如果您使用'create或replace',則不會如您所在。但我認爲我沒有看到這種行爲記錄。 –

+0

假設任何DDL語句都是事務處理的連續屬性應該保留的含義提交...那就是你不應該錯過事件。但是,如果明確說明,這將會很有趣。 – Claude

回答

0

我想你可能會以錯誤的方式進行測試。您的插入語句根本不需要任何時間,因此觸發器的更換可以通過插入之間的間隙進入。至少這是我推斷由於下面。

如果您更改測試以確保您有長時間運行的SQL語句,例如

create table test_trigger (id number); 
create table test_trigger_h (id number); 
create sequence test_trigger_seq; 

create or replace trigger test_trigger_t 
after insert on test_trigger for each row 
begin 
    insert into test_trigger_h (id) values (:new.id); 
end;  
/

insert into test_trigger 
select level 
    from dual 
connect by level <= 1000000; 

如果再嘗試更換觸發器中也不會發生,直到完成插入後單獨會話。

不幸的是,我找不到任何文件來支持我;這只是我意識到的行爲。

1

create or replace正在鎖定表格。所以所有的插入都會等到它完成。不要擔心錯過的插入。

0

以下URL回答了觸發器可以在應用程序運行時被修改。它將會有一個「庫緩存」鎖而不是一個「數據」鎖。 Oracle在內部處理它,而不用擔心它。由本 - Can a trigger be locked; how would one determine that it is?

提出

退房的問題 - 從會話2運行此: SELECT * FROM V $訪問其中的對象=上( 'test_trigger_t');

相關問題