Ist es möglich, Oracle-Datenbankprozeduren dazu zu bringen, Commit-Anweisungen zu ignorieren?

8

Ich arbeite an einer Java-Anwendung, die in Oracle PL / SQL geschrieben ist. Leider kann ich dieses Legacy-System nicht ändern. Problem mit diesem System ist, dass manchmal COMMIT-Anweisungen in Prozeduren geschrieben werden. Dies führt jedoch dazu, dass ich Transaktionen auf meiner Anwendungsebene nicht korrekt verarbeiten kann.

Ist es also möglich, Oracle-Datenbankprozeduren dazu zu bringen, Commit-Anweisungen zu ignorieren?

Ich habe festgestellt, dass die Ausführung von ALTER SESSION DISABLE COMMIT IN PROCEDURE beim Start der Verbindung eine Ausnahme verursacht, wenn die PL / SQL-Prozedur versucht, zu committen. Aber ist es möglich, Oracle dazu zu bringen, Commit zu ignorieren, ohne den PL / SQL-Code zu ändern?

    
sveneller 20.06.2013, 05:53
quelle

6 Antworten

6

Ich glaube nicht, dass Sie das tun können. Sie müssen diesen Prozeduren einen Parameter hinzufügen, wie "commit" mit dem Standardwert true. Und Sie rufen sie mit Parameter auf false gesetzt. Übergeben Sie den Parameterwert, wenn sie verschachtelt sind. Auf diese Weise verhält sich der Legacy-Code immer noch gleich, aber Sie erhalten die Transaktionskontrolle.

    
Tilman Fliegel 22.06.2013 04:05
quelle
5

Ich arbeite jetzt seit 9 Jahren mit Oracle zusammen. Ich habe auch undokumentierte Parameter in Bezug auf Ihre Frage überprüft und ich bin ziemlich sicher, dass es keine Möglichkeit gibt, Oracle ein Commit einer gespeicherten Prozedur ignorieren zu lassen.

Aber theoretisch können Sie die Flashback-Funktion von Oracle (z. B. Flashback-Datenbank oder Flashback-Tabelle) verwenden, um die gesamte Datenbank oder einzelne Tabellen in einen Zustand zurückzusetzen, bevor die Transaktion gestartet wurde. Aber sei dir bewusst, dass dies nur wie gewünscht funktioniert, wenn du der Einzige bist, der etwas an den Objekten ändert, die du zurückblitzest. Dies ist normalerweise unrealistisch. Übrigens müssen Sie auch berücksichtigen, dass die Flashback-Funktion nicht dafür ausgelegt ist, ein solches Szenario zu unterstützen, sodass die Leistung Ihrer Anwendung für den Fall, dass Sie etwas zurückblitzen müssen, nicht optimal ist. Aber dies kann ein Weg sein, um Ihr Problem zu lösen, wenn Sie keine andere Wahl haben.

    
Roman Krüger 26.06.2013 10:47
quelle
2

Wahrscheinlich ist es das Beste, die pl / sql-Prozeduren zu ändern, ohne die aktuelle Funktionalität zu beeinträchtigen. Mit anderen Worten, füge einen neuen Parameter hinzu, der es dem Benutzer erlaubt, Commits zu ignorieren, aber die existierende Funktionalität zu übernehmen (zu committen). Ich habe das in einer ähnlichen Situation gemacht und es hat gut funktioniert.

Sie hätten also etwas wie:

%Vor%

Stellen Sie sicher, dass dieser neue Parameter am Ende der Parameterliste hinzugefügt wird. Ihre App würde also 0 (falsch) für i_commit übergeben.

Ich hoffe, das hilft.

    
tbone 28.06.2013 14:55
quelle
0
  

Ich habe festgestellt, dass ALTER SESSION DISABLE COMMIT IN PROCEDURE   Zu Beginn der Verbindung wird beim PL / SQL-Verfahren eine Ausnahme ausgelöst   versucht zu begehen.

Ja, das dokumentierte Verhalten dieser Anweisung besteht darin, ORA-00034-Ausnahmen zu erzwingen, wenn eine Prozedur versucht, eine Festschreibung auszuführen. Ich denke, es ist wirklich eine Testaufgabe, um Prozeduren mit eingebetteten Commits zu identifizieren.

Ich denke, es wird allgemein als schlechte Praxis angesehen, gespeicherte Prozeduren Commits auszugeben. Die Steuerung der Transaktion muss zum Anfang des aufrufenden Stacks gehören.

Leider gibt es keine Möglichkeit, diese eingebetteten Commits zu ignorieren. Sie müssen entweder die PL / SQL-Routinen neu schreiben oder einige Problemumgehungen in Ihrem aufrufenden Code (z. B. Ausnahmebehandler, der zusätzliche DML ausgibt, um festgeschriebene Änderungen rückgängig zu machen) programmieren.

    
APC 26.06.2013 10:27
quelle
0

Zu wissen, was das Verfahren getan hat, wäre hilfreich gewesen. Unter der Annahme, dass die Prozedur Daten in einer begrenzten Anzahl von Tabellen ändert (das ist es, was wir sowieso meistens in PLSQL tun), könnten Sie versuchen, eine Flashback-Abfrage für dieses Schema auszuführen:

FLASHBACK TABLE TABLE_NAME zu TIMESTAMP (TO_DATE ('06-SEP-2012 23:59:59 ',' DD-MON-YYYY HH24: MI: SS '));

Sie können die Zeitzeichenfolge "06-SEP-2012 23:59:59" auf die Zeit setzen, unmittelbar bevor die Prozedur in Ihrem JAVA-Code aufgerufen wird.

Es ist ein schlechter Workaround, aber einen Versuch wert, denke ich

    
Arnab 30.06.2013 18:57
quelle
0
  

Ich arbeite an einer Java-Anwendung, die in das Legacy-System integriert ist   geschriebenes Oracle PL / SQL. Leider kann ich das nicht ändern   Altsystem.

Hmmm, das riecht nach Politik ... "Fass das nicht an, es funktioniert!" Ich vermute. : (

Tatsächlich ist es höchstwahrscheinlich unmöglich, eine COMMIT Aussage zu ignorieren, wie @ Tilman Fliegel (und andere) bereits gesagt haben. Und wenn es so wäre, wäre es eine ziemlich hässliche Warze in deiner Codebasis.

Ich bin nicht so gut in der Politik, aber ich würde sagen, wenn du dieses nicht benutzen oder ändern kannst, dann benutze das einfach nicht . Ich meine:

  • Wenn Sie Ihre Prozeduren nicht ändern können, weil sie von anderen (alten, unveränderlichen) Systemen verwendet werden, dann duplizieren Sie sie, und modifizieren / refobieren Sie Ihre Kopie, bis Sie damit zufrieden sind. Wenn Sie Ihre Version retro-kompatibel machen können, können Sie sogar anderen (alten) Systemen die Möglichkeit geben, Ihre nachher zu verwenden, wenn sie refaktoriert werden: Führen Sie einfach einen Eingabeparameter "Legacy-Modus" oder was auch immer ein, vgl . andere Antworten.
  • Wenn Sie den Code nicht ändern können, weil Sie ihn nicht verstehen / testen können, ist dies ein großes Problem. Es ist vielleicht sogar sicherer, es einfach wegzuwerfen und von vorne anzufangen (sofern Sie dazu in der Lage sind).

Aber vielleicht ist es einfacher, den COMMIT s zu ignorieren. Menschen sind so schwer zu reformieren ...;)

    
Vincent 01.07.2013 13:30
quelle

Tags und Links