2012-04-13 2 views
1

У меня есть после обновления триггера (Trigger A) на таблицу А, которая может внести изменения в таблицу В.Как избежать ORA-04091 ошибка в триггере

Я также иметь после запуска обновления (Trigger B) на таблица B, которая не вносит никаких изменений, но запрашивает таблицу A для проверки правильности денормализации.

Так Trigger B может стрелять один из двух способов:

  1. если я непосредственно обновляющих таблицу В, или
  2. если я обновить таблицу A и Trigger А пожары, в результате чего обновление таблицы B

В случае 2, я получаю ORA-04091: имя таблицы мутирует, триггер/функция может не увидеть его ошибку. Это кажется правильным.

Я хочу проверить внутри триггера B, если таблица A «в плохом состоянии» и ранний выход (в этом случае проверка работоспособности в этом случае не требуется).

Каков наилучший способ проверить это в течение моего триггера? Просто добавьте обработчик исключений, который проглатывает исключение? Есть ли что-то более изящное?

ответ

2

У вас может быть спусковой крючок на A, чтобы предупредить спусковой механизм на B, что его не нужно стрелять. Есть разные желания настроить какое-то состояние для сеанса. Простейшим возможным подходом было бы сделать что-то вроде создания пакета с логической переменной bypass_checks_on_b, которую вы установили на TRUE, прежде чем вы сделаете UPDATE на A, установите значение FALSE после завершения UPDATE, а затем проверьте состояние этой переменной в триггере на B, прежде чем выполнять свои проверки. Вы могли бы сделать что-то подобное с временной таблицей или контекстом, а не с использованием пакета. Менее эффективно вы можете проанализировать стек вызовов внутри вашего триггера на B, чтобы узнать, является ли триггер на A в стеке вызовов, но это будет иметь тенденцию быть довольно уродливым.

Я бы очень осторожно относился к этой архитектуре. Когда вы обнаружите, что у вас есть триггеры на A, которые вызывают срабатывания триггеров на B, которые хотели бы запросить A, почти всегда бывает, что вы задействовали слишком много логики в триггерах и что вам будет гораздо лучше обслуживать перемещение эта логика в уровень хранимой процедуры, который может быть вызван, а не приложения, выполняющие прямые вставки или обновления. Когда вы вводите слишком много логики в триггеры, вы получаете систему, которую очень сложно понять, потому что не видно из рассмотрения кода приложения, какие побочные эффекты имеют различные утверждения. И в итоге вы получаете код с очень высоким кодом, в котором у вас есть много путей через единый код в зависимости от вызывающего. Это почти наверняка означает, что будут состояния, в которых вы не тестируете или не думаете, где вы обнаружите, что ваш код делает что-то неожиданное. Между наличием тонны состояния и наличием кодовой базы с тонны побочных эффектов вы очень быстро можете создать базу кода, которая по существу не поддается контролю.

+0

Я полностью согласен, но так оно и есть. Пакетное решение, похоже, делает трюк, спасибо! –

 Смежные вопросы

  • Нет связанных вопросов^_^