Можно ли заменить точки сохранения для запуска новых транзакций в Oracle? - PullRequest
6 голосов
/ 03 октября 2009

Прямо сейчас процесс, который мы используем для вставки наборов записей, выглядит примерно так:

(и обратите внимание, что «набор записей» означает что-то вроде записи человека вместе с его адресами, номерами телефонов или любыми другими объединенными таблицами).

  1. Начать транзакцию.
  2. Вставьте набор связанных записей.
  3. Подтвердить, если все прошло успешно, в противном случае откат.
  4. Вернитесь к шагу 1 для следующего набора записей.

Должны ли мы делать что-то более подобное?

  1. Запустить транзакцию в начале скрипта
  2. Начать точку сохранения для каждого набора записей.
  3. Вставить набор связанных записей.
  4. Откат к точке сохранения в случае ошибки, продолжить, если все прошло успешно.
  5. Передать транзакцию в начале скрипта.

После некоторых проблем с ORA-01555 и прочтения нескольких статей Ask Tom (например, this ) я подумываю попробовать второй процесс. Конечно, как отмечает Том, начало новой транзакции должно определяться потребностями бизнеса. Стоит ли опробовать второй процесс или это плохая идея?

Ответы [ 2 ]

5 голосов
/ 04 октября 2009

Транзакция должна быть значимой единицей работы. Но то, что составляет Единицу Работы, зависит от контекста. В системе OLTP единица работы - это один человек, вместе с информацией об адресе и т. Д. Но звучит так, как будто вы реализуете какую-то форму пакетной обработки, которая загружает много людей.

Если у вас есть проблемы с ORA-1555, это почти наверняка, потому что у вас есть длительный запрос, предоставляющий данные, которые обновляются другими транзакциями. Фиксация внутри вашего цикла способствует циклическому использованию сегментов UNDO и, следовательно, будет увеличивать вероятность того, что сегменты, на которые вы полагаетесь для обеспечения согласованности чтения, будут повторно использованы. Так что не делать это, вероятно, хорошая идея.

Вопрос о том, является ли использование SAVEPOINTs решением, является другим вопросом. Я не уверен, какое преимущество это даст вам в вашей ситуации. Поскольку вы работаете с Oracle10g, возможно, вам следует рассмотреть вместо этого массовое протоколирование ошибок DML .

В качестве альтернативы вы можете переписать управляющий запрос, чтобы он работал с небольшими порциями данных. Не зная больше о специфике вашего процесса, я не могу дать конкретный совет. Но в целом вместо открытия одного курсора для 10000 записей может быть лучше открыть его двадцать раз для 500 строк в секунду. Другая вещь, которую стоит рассмотреть, - можно ли сделать процесс вставки более эффективным, скажем, с помощью массового сбора и FORALL.

1 голос
/ 03 октября 2009

Некоторые мысли ...

  1. Мне кажется, что одним из пунктов ссылки на asktom было определение размера отката / отмены, чтобы избежать 1555-х годов. Есть ли какая-то причина, по которой это невозможно? Как он отмечает, купить диск гораздо дешевле, чем писать / поддерживать код, чтобы справиться с ограничениями отката (хотя мне пришлось сделать двойной дубль после прочтения ценовой метки в 250 долларов США для накопителя на 36 Гб - этот поток начался в 2002 ! Хорошая иллюстрация закона Мура!)
  2. Эта ссылка (Burleson) показывает одну возможную проблему с точками сохранения.
  3. Является ли ваша транзакция действительными шагами 2,3 и 5 во втором сценарии? Если так, то это то, что я бы сделал - зафиксировать каждую транзакцию. Звучит немного как сценарий 1 - это набор транзакций, объединенных в одну?
...