автономная_транзакция при нарушении триггера и ограничения - PullRequest
4 голосов
/ 19 сентября 2011

Я столкнулся с интересной ситуацией, когда экспериментировал с автономной транзакцией.Рассмотрим следующую ситуацию (обратите внимание, что она не предназначена для такой записи: просто доказательство концепции):

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 Ответ

1 голос
/ 19 сентября 2011

PRAGMA AUTONOMOUS TRANSACTION сохраняет контекст, открывает другой сеанс и что-то делает.Фиксация обязательна, потому что иначе изменения будут потеряны.Вы можете понять, что только изменения, внесенные в некоторый блок в базе данных, имеют смысл в этом сеансе (автономном).

Таким образом, в вашем триггере вы ничего не делаете.Эта переменная: new.changed «изменяется» в другом сеансе, если мы можем сказать это в этом режиме.Это не изменяется для вашего обновления.

...