Когда совершать транзакции в пакетной процедуре?Это хороший вопрос, хотя он кажется только смутно связанным с проблемами с кодом, который вы публикуете.Но давайте все равно ответим.
Нам нужно выполнить коммит, когда процедура PL / SQL завершила единицу работы.Единица работы - это бизнес-операция.Обычно это будет в конце программы, последний оператор перед разделом ИСКЛЮЧЕНИЕ.
Иногда даже не тогда.Решение о коммите или откате должным образом принимается за вершину стека вызова.Если наш PL / SQL вызывается из клиента (может пользователь нажимает кнопку на экране), возможно, клиент должен выполнить коммит.
Но для пакетного процесса вполне разумно управлять своим собственнымcommit (и откат в случае ошибок).Но суть в том, что единственная самая верхняя процедура должна выдавать COMMIT.Если процедура вызывает другие процедуры, эти вызываемые программы не должны создавать коммитов или откатов.Если они должны обработать какие-либо ошибки (журнал и т. Д.) И повторно вызвать их в вызывающей программе.Пусть расшифрует, нужно ли откатываться.Поскольку все вызываемые процедуры выполняются в одном и том же сеансе и, следовательно, в одной и той же транзакции: откат в вызываемой программе отменит все изменения в пакетном процессе.Это не правильно.То же самое относится и к коммитам.
Иногда вы будете читать советы по использованию прерывистых коммитов для разбиения длительных процессов на более мелкие блоки, например, каждые 1000 вставок.Это плохой совет по нескольким причинам, не все они связаны с транзакциями.Соответствующие из них:
- Создание коммита освобождает блокировки ресурсов.Это является причиной
ORA-1555 Snapshot too old
ошибок. - Это также влияет на согласованность чтения, которая применяется только на уровне оператора и / или транзакции.Это является причиной ошибок
ORA-1002 Fetch out of sequence
. - Это влияет на перезапуск.Если программе не удается обработать 30% записей, можем ли мы быть уверены, что она обработает оставшиеся 70% только при повторном запуске пакета?
- После того, как мы зафиксировали записи, другие сеансы смогут увидеть эти изменения:для других пользователей имеет смысл видеть частично измененное представление данных?
Итак, слова «мудрости Oracle» таковы: всегда выравнивайте транзакцию базы данных с бизнес-транзакцией с помощью одного коммитаза единицу работы.
Кто-то упоминал автономные транзакции как способ выдачи коммитов в подпроцессах.Обычно это плохая идея.Изменения, сделанные в автономной транзакции, видны другим сеансам, но не нашим собственным.Это очень редко имеет смысл.Это также создает те же проблемы с перезапуском, что я обсуждал ранее.
Единственное приемлемое использование для автоматических транзакций - запись активности (журнал ошибок, трассировка, записи аудита).Нам нужны эти данные для сохранения независимо от того, что происходит в более широкой транзакции.Любое другое использование прагмы - это почти наверняка обходной путь для дизайна porr, который на самом деле только усугубляет проблему.