2009-10-03 3 views
6

Im Moment ist der Prozess, den wir für das Einfügen von Datensätze verwenden, etwa folgendermaßen:Kann ich Savepoints zum Starten neuer Transaktionen in Oracle ersetzen?

(und beachten Sie, dass "Satz von Datensätzen" so etwas wie den Datensatz einer Person zusammen mit ihren Adressen, Telefonnummern oder anderen andere verbundene Tabellen).

  1. Starten Sie eine Transaktion.
  2. Fügen Sie eine Reihe von Datensätzen ein, die verwandt sind.
  3. Commit, wenn alles erfolgreich war, Rollback andernfalls.
  4. Gehen Sie zurück zu Schritt 1 für die nächste Reihe von Datensätzen.

Sollten wir etwas mehr so ​​machen?

  1. am Anfang des Skripts Starten Sie eine Transaktion
  2. ein Punkt für jeden Satz von Datensätzen speichern starten.
  3. Fügen Sie eine Reihe verwandter Datensätze ein.
  4. Rollt bei einem Fehler zum Sicherungspunkt zurück, wenn alles erfolgreich ist.
  5. Commit die Transaktion am Anfang des Skripts.

Nachdem ich einige Probleme mit ORA-01555 hatte und einige Artikel von Ask Tom gelesen habe (wie this one), denke ich darüber nach, den zweiten Prozess auszuprobieren. Natürlich, wie Tom hervorhebt, sollte das Starten einer neuen Transaktion von den Geschäftsanforderungen definiert werden. Lohnt sich der zweite Prozess oder ist es eine schlechte Idee?

+1

+1, interessante Frage (auch für die asktom Diskussion) – DCookie

+0

Es wäre nützlich, wenn Sie Ihren aktuellen Wert für UNDO_RETENTION und die Zeit für das Ausführen des gesamten Skripts und die Verarbeitung von jedem Satz. –

Antwort

5

Eine Transaktion sollte eine sinnvolle Einheit der Arbeit sein. Aber was eine Einheit der Arbeit ausmacht, hängt vom Kontext ab. In einem OLTP-System wäre eine Arbeitseinheit eine einzelne Person, zusammen mit ihren Adressinformationen usw. Aber es klingt so, als ob Sie irgendeine Form der Stapelverarbeitung implementieren, die viele Personen lädt.

Wenn Sie Probleme mit ORA-1555 haben, ist es fast sicher, weil Sie eine lange laufende Abfrage haben, die Daten liefert, die durch andere Transaktionen aktualisiert werden. Die Verwendung innerhalb Ihrer Schleife trägt zur zyklischen Verwendung von UNDO-Segmenten bei und erhöht daher tendenziell die Wahrscheinlichkeit, dass die Segmente, auf die Sie angewiesen sind, um die Lesekonsistenz zu gewährleisten, wiederverwendet wurden. Also, das nicht zu tun, ist wahrscheinlich eine gute Idee.

Ob SAVEPOINTs verwendet wird, ist die Lösung eine andere Sache. Ich bin mir nicht sicher, welchen Vorteil das in Ihrer Situation bringen würde. Da Sie mit Oracle10g arbeiten, sollten Sie stattdessen die Verwendung von Bulk DML error logging in Betracht ziehen.

Alternativ können Sie die treibende Abfrage neu schreiben, so dass sie mit kleineren Datenmengen arbeitet. Ohne mehr über die Besonderheiten Ihres Prozesses zu wissen, kann ich keinen spezifischen Rat geben. Aber im Allgemeinen, anstatt einen Cursor für 10000 Datensätze zu öffnen, könnte es besser sein, sie zwanzig mal für 500 Zeilen pro Pop zu öffnen. Die andere Sache, die in Betracht gezogen werden muss, ist, ob der Einfügeprozess effizienter gemacht werden kann, sagen wir, indem wir Massensammlung und FORALL verwenden.

+0

+1 für das Commit innerhalb einer Schleife. Normalerweise aktualisieren Sie die Datensätze, die Sie in der Schleife auswählen. Es läuft immer noch darauf hinaus, die Retention und Dimensionierung rückgängig zu machen. Sehen Sie sich einen anderen Burleson-Link an (der auf andere verweist): http://www.dba-oracle.com/t_ora_01555_snapshot_old.htm – DCookie

+0

Der Vorteil von Savepoints wäre, dass Oracle nicht gezwungen wäre, Informationen in UNDO länger zu speichern. Ich vermute, dass in Ihrer Gliederung ein Schritt 0 von "Öffne einen Cursor" fehlt. In der ursprünglichen Methode kann das Rückgängigmachen jedes Mal, wenn es Schritt 3 erreicht, verloren gehen, so dass der Cursor aus Schritt 0 1555 erhöhen kann. Bei der neuen Methode muss das Rückgängigmachen bis zum Ende des Skripts beibehalten werden. –

1

Einige Gedanken ...

  1. Scheint mir einer der Punkte, der AskTom Link zu Größe/Ihr Rollbacks der 1555 die entsprechend rückgängig zu vermeiden war. Gibt es einen Grund, warum das nicht möglich ist? Wie er hervorhebt, ist es viel billiger, Disketten zu kaufen, als Code zu schreiben/zu pflegen, um Rollback-Beschränkungen zu umgehen (obwohl ich nach dem Lesen des $ 250 Pricetags für ein 36Gb-Laufwerk einen Doppelklick machen musste) ! Gute Illustration von Moores Gesetz!)
  2. This link (Burleson) zeigt ein mögliches Problem mit Savepoints.
  3. Ist Ihre Transaktion in den Schritten 2, 3 und 5 in Ihrem zweiten Szenario? Wenn ja, würde ich das tun - jede Transaktion festschreiben. Hört sich für mich etwas an, als wäre Szenario 1 eine Sammlung von Transaktionen in einem zusammengefasst?
+0

Ich denke, dass ich im ersten Szenario nicht klar genug gewesen wäre. Grundsätzlich begehen wir im Moment für jeden Satz von Datensätzen (nach Satz von Einträgen meine ich etwas wie eine Person, ihre Adressen und Telefonnummern). Was ich dachte, war, dass dies mehr wie eine große Transaktion ist, die Sicherungspunkte verwendet. –

+0

Ich sehe nicht, warum Sie dann 1555 bekommen. Was versuchen Sie von den Sicherungspunkten zu erreichen? Scheint mir, Sie sind eher die 1555 Fehler im zweiten Szenario zu bekommen? – DCookie

+0

Durch häufiges Commit werden Datensätze über mehrere Undo-Segmente verteilt. Dies macht es wahrscheinlicher, dass Transaktionen überschrieben werden und die Wahrscheinlichkeit eines ORA-01555 erhöht wird. In der Tat, häufiger commits nehmen * mehr * undo Raum: http://oradbdev.blogspot.com/2007/04/commit-frequency-and-undo.html –

Verwandte Themen