2009-10-03 7 views
6

現在、レコードのセットを挿入するプロセスは、次のようなものです:オラクルで新しいトランザクションを開始するためにセーブポイントを代用できますか?

(「レコードのセット」とは、住所、電話番号、その他他の結合テーブル)。

  1. トランザクションを開始します。
  2. 関連する一連のレコードを挿入します。
  3. すべて成功した場合はコミットし、それ以外の場合はロールバックします。
  4. 次のレコードセットについては、手順1に戻ります。

このようなことをする必要がありますか?

  1. は、レコードのセットごとにポイントを保存開始スクリプトの開始時にトランザクションを開始します。
  2. 関連するレコードのセットを挿入します。
  3. エラーが発生した場合はセーブポイントにロールバックし、すべて成功した場合は続行します。
  4. スクリプトの先頭にトランザクションをコミットします。

ORA-01555に問題があり、Ask Tomの記事(this oneなど)を読んだ後、2番目のプロセスを試してみることを考えています。もちろん、Tomが指摘するように、新しいトランザクションの開始は、ビジネスニーズによって定義されるべきものです。 2番目のプロセスは試してみる価値がありますか、それとも悪い考えですか?

+1

+1(興味深い質問) – DCookie

+0

UNDO_RETENTIONの現在の値とスクリプト全体の実行に要した時間と各セットの処理に役立つでしょう。 –

答えて

5

トランザクションは意味のある単位作業でなければなりません。しかし、作業単位を構成するものは、文脈に依存します。 OLTPシステムでは、Unit Of Workはアドレス情報などとともに、単一のPersonになります。しかし、多くのPersonをロードしている何らかの形式のバッチ処理を実装しているかのように聞こえます。

ORA-1555に問題がある場合、他のトランザクションによって更新されているデータを提供する長い実行クエリがあるため、ほぼ確実です。ループ内でのコミットは、UNDOセグメントの循環使用に寄与します。したがって、読取り一貫性を提供するために依存しているセグメントが再利用される可能性が高くなります。だから、そうしないのはいい考えです。

SAVEPOINTを使用するかどうかは、別の問題です。あなたの状況にどんな利点があるのか​​は分かりません。おそらくOracle10gで作業しているので、代わりにバルクDML error loggingを使用することを検討する必要があります。

また、ドライブクエリーを書き換えて、より小さなデータチャンクで動作させることもできます。あなたのプロセスの詳細を知らずに、私は具体的な助言をすることはできません。しかし、一般的に、10000レコードに対して1つのカーソルを開くのではなく、ポップとして500行に20回開くのが良いかもしれません。考慮すべきもう1つの点は、挿入プロセスがバルクコレクションとFORALLを使用するなど、より効率的にできるかどうかです。

+0

ループ内のコミットの+1。通常これは、ループで選択しているレコードを更新するときです。保持とサイジングを元に戻すためにはまだ沸騰しています。他のBurlesonのリンクを参照してください(他の人を参照してください):http://www.dba-oracle.com/t_ora_01555_snapshot_old.htm – DCookie

+0

セーブポイントの利点は、オラクルが情報をUNDOに長く保持することを余儀なくされることです。私はあなたのアウトラインが "カーソルを開く"のステップ0を欠いていると思う。元の方法では、ステップ3に達するたびに元に戻すことができないため、ステップ0のカーソルは1555を上げることができます。新しいメソッドでは、元に戻すスクリプトの最後まですべてを保持する必要があります。 –

1

いくつかの考え...

  1. はasktomリンクのポイントの一つは、あなたのロールバック/ 1555年代を避けるために適切に元に戻すの大きさにした私には思えます。これができない何らかの理由はありますか?彼が指摘しているように、ディスクを購入するのは、ロールバックの制限を回避するためにコードを書いたり維持したりするよりもずっと安いです(私は36Gbドライブの$ 250のpricetagを読んだ後に二重テイクをしなければなりませんでした。 !ムーアの法則の良いイラスト!)
  2. This link (Burleson)は、セーブポイントに関する1つの可能な問題を示しています。
  3. 2番目のシナリオでは、トランザクションは実際に2,3、および5ステップですか?もしそうなら、それは私がやることです - それぞれのトランザクションをコミットします。シナリオ1が1つに集められたトランザクションの集まりであるように私に少し聞こえる?
+0

私は最初のシナリオでは十分にはっきりしていないかもしれないと思います。基本的には今、私たちはレコードのセットごとにコミットしています(レコードのセットでは、人、そのアドレス、電話番号などを意味します)。私が考えていたのは、これをセーブポイントを使用する大きなトランザクションのようにすることでした。 –

+0

私はあなたが1555を得ている理由を見ません。あなたはセーブポイントから何を得ようとしていますか? 2番目のシナリオで1555のエラーが発生する可能性が高いと思いますか? – DCookie

+0

頻繁にコミットすると、いくつかのUNDOセグメントにレコードが散在することになります。これにより、トランザクションが上書きされ、ORA-01555の可能性が高くなる可能性が高くなります。実際、より頻繁なコミットは* more *空間を取り消します:http://oradbdev.blogspot.com/2007/04/commit-frequency-and-undo.html –

関連する問題