Мне нужно выполнить несколько (до ~ 1000000) SQL-операторов в базе данных Oracle. Эти операторы должны приводить к окончательно согласованному состоянию в конце, и все операторы должны откатываться в случае возникновения ошибки. Эти заявления не приходят в ссылочном порядке. Поэтому, если включены ограничения внешнего ключа, одно из операторов может вызвать нарушение внешнего ключа, даже если это нарушение будет исправлено с помощью оператора, который будет выполнен позже.
Сначала я попытался отключить внешние ключи и включить их после выполнения всех операторов. Я думал, что смогу откатиться, когда произошло фактическое нарушение внешнего ключа. Хотя я ошибся, я обнаружил, что каждый оператор DDL в Oracle начинался с коммита, поэтому откатить операторы таким способом было невозможно. Вот мой скрипт для отключения внешних ключей:
begin
for i in (select constraint_name, table_name from user_constraints
where constraint_type ='R' and status = 'ENABLED')
LOOP execute immediate 'alter table '||i.table_name||' disable constraint
'||i.constraint_name||'';
end loop;
end;
После некоторых исследований я обнаружил, что рекомендуется выполнять операторы DDL, как в этом случае, в автономной транзакции. Поэтому я попытался выполнить операторы DDL в автономной транзакции. Это привело к следующей ошибке:
ORA-00054: ресурс занят и получен с указанным значением NOWAIT
Я предполагаю, что это потому, что основная транзакция все еще имеет блокировку DDL для таблиц.
Я что-то здесь не так делаю или есть другой способ заставить этот сценарий работать?