Хотя использование автономных транзакций технически является способом избежать ORA-04091, я не рекомендую использовать его по двум причинам:
1.Автономная транзакция не может видеть незафиксированные изменения транзакции вызывающей стороны. Например, триггер, аналогичный приведенному выше решению, не дает правильного результата в следующем случае:
delete from employees;
insert into employees (id, name, salary) values (1, 'A', 5000);
insert into employees (id, name, salary) values (2, 'B', 1000);
commit;
update employees set salary=800 where id=1;
update employees set salary=100 where id=2;
select * from employees;
Во время второго обновления оператор выбора в триггере не может увидеть результат первого обновления, он увидит исходное значение 5000, а не 800. Но, конечно, он может работать в некоторых случаях.
2.Другая причина избежать этого - только личное предложение. Если вы используете толстый клиент, я рекомендую создать хранимую процедуру update_salary, которая сначала проверяет бизнес-правила, вычисляет суммы, и, наконец, выдает команду update сотрудники ....
Или, если вы создаете тонкий клиент или используете постоянный API-интерфейс, вы должны сделать это на сервере приложений (например, EJB). В обоих случаях код будет удобочитаемым и поддерживаемым.