2013-08-26 3 views
6

Mi chiedo se mi perderò qualche dato se sostituisco un trigger mentre il mio database Oracle è in uso. Ho creato un esempio di giocattolo e sembra che non lo farò, ma uno dei miei colleghi afferma il contrario.Mi mancheranno le modifiche se sostituisco un trigger di Oracle mentre la mia applicazione è in esecuzione?

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

Interessante. Mi aspetterei che gli eventi manchino se si separano le istruzioni 'drop' e' create'; ma non se usi 'crea o sostituisci 'come sei qui. Ma non penso di aver visto quel comportamento documentato. –

+0

Supponendo che qualsiasi istruzione DDL sia un commit implicito rispetto alla proprietà sequenziale dell'elaborazione della transazione dovrebbe contenere ... è necessario non perdere eventi. Tuttavia, sarebbe interessante se questo è specificato. – Claude

risposta

0

Penso che si stia andando a testare questo nel modo sbagliato. Le istruzioni di inserimento non impiegheranno affatto del tempo e quindi la sostituzione del trigger può inserirsi negli spazi tra gli inserti. Almeno questo è quello che deduco a causa del sottostante.

Se si modifica il test per assicurarsi di disporre di un'istruzione SQL con esecuzione prolungata, ad es.

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; 

Se quindi si tenta di sostituire il grilletto in una sessione separatanon avverrà fino a dopo l'inserto è stato completato.

Purtroppo, non riesco a trovare nulla nella documentazione per sostenermi; questo è solo un comportamento di cui sono a conoscenza.

1

create or replace sta bloccando il tavolo. Quindi tutti gli inserti attenderanno fino al completamento. Non preoccuparti per gli inserti persi.

0

Le risposte URL successive al trigger possono essere modificate mentre l'applicazione è in esecuzione. è un blocco "cache della libreria" e NON un blocco "dati". Oracle lo gestisce internamente senza preoccuparti di ciò.

Partenza questione sollevata da Ben Can a trigger be locked; how would one determine that it is?

- Eseguire questo dalla sessione 2: select * from v $ accesso dove l'oggetto = superiore ('test_trigger_t');

Problemi correlati