2013-08-26 10 views
6

Zastanawiam się, czy będę tęsknił za jakimikolwiek danymi, jeśli wymienię spust, gdy moja baza danych Oracle będzie w użyciu. Stworzyłem przykład zabawki i wygląda na to, że tego nie zrobię, ale jeden z moich współpracowników twierdzi inaczej.Czy będę tęsknić za wszelkimi zmianami, jeśli wymieniam wyzwalacz Oracle, gdy moja aplikacja jest uruchomiona?

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

Interesujące. Spodziewam się, że zdarzenia zostaną pominięte, jeśli oddzielisz instrukcje 'drop' i' create'; ale nie, jeśli użyjesz opcji "utwórz lub zastąp", tak jak tu jesteś. Ale nie sądzę, że widziałem to zachowanie udokumentowane. –

+0

Załóżmy, że każda instrukcja DDL jest implikowanym zatwierdzeniem, niż powinna zachowywać się sekwencyjna właściwość przetwarzania transakcji ... nie powinieneś przegapiać zdarzeń. Byłoby jednak interesujące, gdyby zostało to określone. – Claude

Odpowiedz

0

Myślę, że możesz chcieć testować to w niewłaściwy sposób. Twoje instrukcje wstawiania nie będą trwać w ogóle, więc wymiana wyzwalacza może zmieścić się w szczelinach między wkładkami. Co najmniej to, co wnioskuję z powodu poniżej.

Jeśli zmienisz test, aby upewnić się, że masz długą instrukcję SQL, np.

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; 

Jeśli następnie spróbuj zastąpić spust w oddzielnym sesji to nie nastąpi, dopóki wkładka została zakończona.

Niestety, nie mogę znaleźć niczego w dokumentacji, aby mnie wesprzeć; to po prostu moje zachowanie.

1

create or replace blokuje stół. Zatem wszystkie inserty będą czekać, aż się skończą. Nie martw się o pominięte wkładki.

0

Poniższe odpowiedzi URL, że wyzwalacz można zmodyfikować podczas działania aplikacji. jego będzie blokada "biblioteki pamięci podręcznej", a NIE "blokada" danych. Oracle obsługuje je wewnętrznie, nie martwiąc się o to.

Wyjazd kwestia podniesiona przez Ben-Can a trigger be locked; how would one determine that it is?

- Run to z sesji 2: select * from v $ dostępem gdzie obiekt = upper ('test_trigger_t');

Powiązane problemy