Ist ein Festschreiben nach der DML-Operation in Funktion / Prozedur erforderlich?

20

Ich frage mich zu wissen, ob es notwendig ist, ein Commit nach dem Einfügen / Löschen / Aktualisieren in Funktion / Prozedur zu schreiben.

Beispiel:

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

oder Verfahren

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

Muss es nach dem Löschen festgeschrieben werden?

Kann die folgende Situation nicht verstehen:

  1. Wenn ich die Funktion / Prozedur von einem SQL-Fenster aus aufrufe, ist ein Commit erforderlich

    aber

  2. Wenn ich die Funktion / Prozedur mit dbms_scheduler plane und den Job ausführe, wird die Anweisung delete automatisch festgeschrieben.

    WARUM?

Kupa
quelle

Antworten:

24

Im Allgemeinen sollten Verfahren nicht festgeschrieben werden. Diese Art von Transaktionssteuerungsentscheidungen sollten einem Code höherer Ebene überlassen werden, der weiß, wann eine logische Transaktion tatsächlich abgeschlossen ist. Wenn Sie ein Commit innerhalb einer gespeicherten Prozedur durchführen, schränken Sie deren Wiederverwendbarkeit ein, da ein Aufrufer, der die von der Prozedur vorgenommenen Änderungen als Teil einer größeren Transaktion verwenden möchte, die Prozedur nicht einfach direkt aufrufen kann.

Wenn Sie eine Prozedur interaktiv aufrufen, müssen Sie die Transaktion explizit festschreiben oder zurücksetzen, da Oracle nicht weiß, ob der Prozeduraufruf eine logische Transaktion sein soll oder ob Sie eine größere Transaktion mit mehreren Prozeduraufrufen erstellen möchten. Wenn Sie verwenden dbms_scheduler, wird dbms_schedulerdavon ausgegangen , dass ein Job eine logische Transaktion ist, und er wird am Ende des Jobs festgeschrieben, sofern er erfolgreich war ( dbms_jobmacht dasselbe).

Funktionen sollten Daten nicht in erster Linie manipulieren. Eine Funktion, die Daten manipuliert, kann nicht aus einer SQL-Anweisung aufgerufen werden (mit Ausnahme des Eckfalls, in dem die Funktion selbst für die Verwendung einer autonomen Transaktion deklariert ist, die so gut wie nie geeignet ist). Der springende Punkt bei der Verwendung von Funktionen und Prozeduren ist, dass Funktionen in SQL-Anweisungen eingebettet und Benutzern freier gewährt werden können, da sie keine Daten ändern.

Justin Cave
quelle
1
Ist es in Oracle nicht möglich, dass der Aufrufer eine Transaktion startet, die Prozeduraufrufe bindet? In SQL Server können Sie einen Commit innerhalb der Prozedur ausführen. Wenn der Aufrufer jedoch vor dem Aufrufen dieser Prozedur eine Transaktion geöffnet hat, wird erst dann ein Commit ausgeführt, wenn auch der Aufrufer einen Commit ausführt.
Nick Chammas
4
@ NickChammas - Oracle hat nicht das Konzept einer verschachtelten Transaktion, nein. Wenn die Prozedur festgeschrieben wird, wird alles festgeschrieben, was der Anrufer bis zu diesem Zeitpunkt getan hat. Der Aufrufer startet eine Transaktion immer implizit mit seiner ersten Anweisung (unabhängig davon, ob es sich um einen Prozeduraufruf oder etwas anderes handelt), sodass es immer Sache des Aufrufers sein sollte, die Transaktion zu beenden.
Justin Cave
@JustinCave Auch wenn dies zutrifft, sollten Sie autonome Transaktionen nicht vergessen.
Philᵀᴹ
@Phil - Stimmt, aber das ist ein ganz anderes Tier. Eine autonome Transaktion kann die vom Aufrufer vorgenommenen nicht festgeschriebenen Änderungen nicht sehen und kann vom Aufrufer nicht rückgängig gemacht werden, sodass es äußerst unwahrscheinlich ist, dass für eine andere als eine Protokollierungsprozedur die Verwendung einer autonomen Transaktion deklariert werden sollte.
Justin Cave
4

Zur Beantwortung Ihrer Frage; WARUM?

Das wissen Sie wahrscheinlich schon, da die Post 2 Jahre alt ist. Aber ich werde nur für die Aufzeichnung antworten.

Der Grund, warum # 1 ein Commit erfordert und # 2 nicht, ist, dass die Standard-Datenbankeinstellung in Oracle das Commit einer Transaktion ist, wenn eine Sitzung endet. Wenn Sie sich in sqlplus befinden und Ihren Code manuell ausführen, wird die Transaktion nicht sofort festgeschrieben. Wenn Sie ein explizites Commit ausführen ODER sich von sqlpus abmelden, wird die Transaktion festgeschrieben.

Der Grund, warum Sie ein automatisches Commit für # 2 erhalten, besteht darin, dass eine Sitzung zum Ausführen Ihres Skripts erstellt wird. Wenn es abgeschlossen ist, wird es automatisch abgemeldet, was zu einem automatischen Festschreiben führt.

Steve Cunningham
quelle