Обработка данных в глобальных временных таблицах в случае отката транзакции

У меня есть задание, которое выполняется с несколькими экземплярами, т. е. кодовая база для всех экземпляров одинакова, но каждый экземпляр работает с набором выделенных ему данных, чтобы добиться параллелизма и лучшей пропускной способности для приложения. Эти задания используют глобальную временную таблицу для обработки данных, поскольку перед вычислением окончательного вывода выполняется несколько сложных операций. В случае неудачи транзакция откатывается (как и должно быть), но при этом у меня тоже теряются данные в gtt.

Есть ли способ скопировать записи в gtt в другую постоянную таблицу при откате транзакции. Я знаю, это звучит странно, но это практическая проблема, с которой я столкнулся. Мне нужно каким-то образом сохранить данные в таблице сеансов в случае сбоя любого sql, при откате транзакции, так как один из sql не удался.

Спасибо.


person Kailash    schedule 19.08.2019    source источник
comment
Почему вы не используете вложенные таблицы вместо временных? Таким образом, вам не нужно беспокоиться о транзакциях, а также может быть быстрее, поскольку нет переключения контекста между pl/sql и sql-движком?   -  person Radagast81    schedule 19.08.2019
comment
Временная таблица используется, поскольку существует несколько сеансов (экземпляры, о которых я упоминал выше), все они работают с одним и тем же набором таблиц. С временными таблицами мне не нужно беспокоиться о том, что данные будут затронуты другим сеансом. Чтобы справиться с этим во вложенных таблицах, мне придется добавить дополнительные предложения, не так ли?   -  person Kailash    schedule 19.08.2019
comment
@ Radagast81 - под вложенными таблицами я полагаю, вы имеете в виду коллекции PL/SQL. Это объекты памяти сеанса, поэтому вероятность постоянного сохранения данных, как того требует OP, невелика.   -  person APC    schedule 19.08.2019
comment
Да, я имею в виду коллекции PL/SQL. Они сохраняются в пакете даже после фиксации/отката, пока сеанс жив, и ограничиваются текущим сеансом, поэтому вам не нужно беспокоиться о том, что на вас повлияет другой сеанс. Я не знаю, насколько актуальны данные, но обычно до завершения сеанса достаточно.   -  person Radagast81    schedule 19.08.2019
comment
@ Кайлаш - пожалуйста, уточните. Ваши GTT определены как ON COMMIT PRESERVE или ON COMMIT DELETE? Если СОХРАНИТЬ, почему вы теряете данные? Это потому, что сбой вашего процесса завершает сеансы?   -  person APC    schedule 19.08.2019
comment
@APC, откат приведет к сбросу данных gtt.   -  person Popeye    schedule 19.08.2019
comment
@tejash - если GTT определены как ON COMMIT PRESERVE ROWS и процесс выдает коммиты сразу после заполнения GTT перед началом какой-либо транзакционной работы, то я полагаю, что в GTT все еще будут данные после транзакции. abends и выдает откат. Вот почему нам нужно знать подробности того, что делает ОП.   -  person APC    schedule 19.08.2019
comment
Gtt определяются как сохранение строк при фиксации. Кроме того, они используют несколько функций C для одних и тех же исполняемых файлов и процедур базы данных, и существует множество SQL-запросов, выполняемых как через C-код, так и через процедуры. Таким образом, иметь один блок begin-end невозможно.   -  person Kailash    schedule 19.08.2019
comment
Как только выдается откат, данные сбрасываются из gtt.. как упоминал Теджаш. Мне нужно проверить код, выдается ли фиксация после заполнения gtt или нет.   -  person Kailash    schedule 19.08.2019


Ответы (2)


Хм, может как-то так:

  • создать постоянную таблицу, в которой будут храниться данные GTT в случае сбоя
  • создать автономную процедуру транзакции, которая будет insert into permanent select * from gtt и commit
  • в разделе обработчика исключений вызовите эту процедуру, а затем rollback
person Littlefoot    schedule 19.08.2019
comment
Я думаю, gtt не покажет никаких данных в автономной транзакции. - person Popeye; 19.08.2019
comment
@Tejash - не обязательно. Транзакция может выбирать содержимое GTT в коллекции PL/SQL и передавать массивы процедуре, которая заполняет постоянную таблицу в рамках автономной транзакции. Хотя я не большой поклонник такого подхода: кажется, что слишком много движущихся частей в том, что по сути является обработчиком исключений. Но я полагаю, это потому, что архитектура OP изначально несколько хрупкая. - person APC; 19.08.2019
comment
Хороший!! Кажется хорошим обходным путем, но ответ должен включать его и удалить select * from gtt - person Popeye; 19.08.2019
comment
Возвращаясь к комментарию APC о необходимости знать подробности: данные GTT также будут видны автономной процедуре, если ее вставка будет зафиксирована (очевидно, до того, что вызвало откат). Даже после отката потом выдается. Немного менее запутанный, но все же может быть непрактичным для ОП. - person Alex Poole; 19.08.2019
comment
Я испытываю искушение попробовать этот подход с автономными процедурами, но это произойдет только завтра. Я обновлю, если это сработало или нет. Сначала я скептически относился к тому, сможет ли автономная транзакция видеть данные в gtt, но похоже, что да. Нет ничего плохого в том, чтобы попробовать пример кода, чтобы увидеть, работает он или нет. Спасибо - person Kailash; 19.08.2019
comment
Итак, я вижу 2 подхода: 1) данные таблицы сеанса видны автономной транзакции, если сеанс зафиксирован после вставки/обновления в таблице сеанса. 2) Таблица сеансов, заполненная автономной транзакцией, видна сеансу задания, если автономная транзакция зафиксирована. Первого пункта трудно достичь, так как это будет означать, что выполняются частичные фиксации и потребуются накладные расходы на откат изменений в случае, если бизнес-транзакция должна быть откатана. Второй утомительный, но достижимый .. Я могу продвинуться по этим направлениям .. Спасибо всем за ваш ответ. - person Kailash; 20.08.2019
comment
@Kailash - вам нужно только зафиксировать данные GTT; если вы можете заполнить и зафиксировать это, прежде чем вносить какие-либо изменения в свои реальные данные таблицы, тогда автономная транзакция увидит GTT (но не другие изменения), и вы все равно сможете откатить изменения реальной таблицы из вашего обработчика исключений. - person Alex Poole; 20.08.2019
comment
Да, я понимаю это. Но заполнить и зафиксировать GTT до внесения изменений в данные реальной таблицы невозможно, так как происходит сочетание вставки/обновления GTT и других таблиц. Поэтому я подумал, что было бы лучше иметь автономную транзакцию для вставки/обновления GTT. Автономная транзакция будет выдавать коммиты после заполнения/обновления GTT, что не будет препятствовать изменениям в других таблицах, поэтому я подумал, что это будет предпочтительным подходом для поставленной задачи. - person Kailash; 20.08.2019

Единственный способ — распечатать необходимые данные перед откатом.

Вы можете использовать UTL_FILE для хранения данных в файле. Позже вы можете использовать external table концепцию оракула для извлечения данных из таблицы.

Ваше здоровье!!

person Popeye    schedule 19.08.2019
comment
Хммм.. Я думаю, это будет немного излишним.. позвольте мне посмотреть, работает ли другой подход или нет. Спасибо. - person Kailash; 19.08.2019