Чи потрібна фіксація після операції DML у функції / процедурі?


20

Цікаво мені знати, чи потрібно писати фіксацію після вставки / видалення / оновлення у функції / процедури?

Приклад:

create or replace function test_fun
return number is
begin
   delete from a;
   return 0;
end;

або процедура

create or replace procedure aud_clear_pro
as
begin
   delete from a;
end;

чи потрібна фіксація після видалення?

Неможливо зрозуміти таку ситуацію:

  1. Якщо я викликаю функцію / процедуру з вікна SQL, тоді вона вимагає фіксації

    але

  2. Якщо я запланую функцію / процедуру за допомогою dbms_scheduler і запускаю завдання, оператор видалення автоматично виконується.

    ЧОМУ?

Відповіді:


24

Загалом, процедури не повинні здійснюватись. Такі рішення щодо контролю транзакцій слід залишити коду вищого рівня, який знає, коли логічна транзакція фактично завершена. Якщо ви здійснюєте всередині збереженої процедури, ви обмежуєте її повторне використання, тому що абонент, який хоче, щоб зміни, які вносить процедура, були частиною більшої транзакції, не можуть просто викликати процедуру безпосередньо.

Якщо ви зателефонуєте на процедуру в інтерактивному режимі, вам доведеться явно здійснити або відмовити транзакцію, оскільки Oracle не має уявлення, чи плануєте ви виклик процедури бути логічною транзакцією або якщо ви маєте намір скласти більшу транзакцію, що включає декілька процедурних дзвінків. Якщо ви користуєтесь dbms_scheduler, dbms_schedulerприпускайте, що робота є логічною транзакцією і здійснює в кінці завдання, вважаючи, що вона була успішною ( dbms_jobробить те ж саме).

Функції не повинні в першу чергу маніпулювати даними. Функцію, яка маніпулює даними, не можна викликати з оператора SQL (заборона кутового випадку, коли сама функція оголошується використовувати автономну транзакцію, що майже ніколи не підходить). Вся суть у функціях та процедурах полягає в тому, що функції можна вбудовувати в оператори SQL і можна вільніше надавати користувачам, оскільки вони не змінюють жодних даних.


1
Чи не можливо в Oracle абонент почати транзакцію, яка пов'язує виклики процедури? У SQL Server ви можете здійснити процедуру всередині процедури, але якщо абонент відкрив транзакцію перед тим, як викликати цю процедуру, нічого не буде вчинено, поки абонент теж не здійснить.
Нік Чаммас

4
@ NickChammas - Oracle не має поняття вкладеної транзакції, ні. Якщо процедура вчиняється, все, що зробив абонент, до цього моменту зробить. Абонент завжди починає транзакцію неявно з першої заяви (чи це виклик процедури, чи щось інше), тому він повинен завжди залежати від оператора, який закінчує транзакцію.
Джастін Печера

@JustinCave Хоча це правда, не забувайте про автономні транзакції.
Philᵀᴹ

@Phil - Правда, але це зовсім інша тварина. Автономна транзакція не може бачити неспроможні зміни, внесені абонентом, і не може бути відкликана абонентом, тому вкрай малоймовірно, що для використання автономної транзакції повинно бути оголошено щось, крім процедури реєстрації.
Джастін Печера

4

Щоб відповісти на ваше запитання; ЧОМУ?

Ви напевно це вже знаєте, оскільки посаді виповнилося 2 роки. Але я відповім лише для запису.

Причина №1 вимагає виконання комісії, а №2 - не тому, що налаштування бази даних за замовчуванням в Oracle полягає в здійсненні транзакції, коли сеанс закінчується. Якщо ви знаходитесь у sqlplus і запускаєте свій код вручну, він не здійснить транзакцію відразу. Якщо ви видаєте явну комісію АБО ви виходите з sqlpus, транзакція буде здійснена.

Причина, за якою ви отримуєте автоматичну фіксацію №2, полягає в тому, що вона створює сеанс для запуску сценарію. Після його завершення він автоматично вимикається, що спричинить автоматичне виконання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.