バッチ処理でトランザクションをコミットするタイミングはいつですか?良い質問ですが、あなたが投稿するコードの問題には漠然と関連しているようです。とにかく答えてみましょう。
PL/SQLプロシージャが作業ユニットを完了したときにコミットする必要があります。作業単位はビジネストランザクションです。これは通常、プログラムの終わり、EXCEPTIONセクションの前の最後のステートメントになります。
時にはそれでもない。コミットまたはロールバックの決定は、呼び出すスタックの先頭にあります。 PL/SQLがクライアントから呼び出されている場合(ユーザーが画面のボタンをクリックしている可能性があります)、クライアントはコミットを発行する必要があります。
しかし、バッチプロセスが独自のコミット(およびエラーの場合はロールバック)を管理することは理にかなっていません。しかし、主なポイントは、最上位のプロシージャだけがCOMMITを発行することです。プロシージャが他のプロシージャを呼び出す場合、プログラムと呼ばれるプロシージャはコミットまたはロールバックを発行すべきではありません。エラーを処理する必要がある場合(ログなど)、呼び出し元のプログラムに再提出してください。ロールバックするかどうかをデコードします。すべての呼び出されたプロシージャは同じセッションで実行され、同じトランザクションで実行されるため、呼び出されたプログラムのロールバックはバッチ処理のすべての変更を元に戻します。それは正しくありません。コミットにも同じ理由が当てはまります。
間欠的コミットを使用して長時間実行されるプロセスをより小さな単位に分割するためのアドバイスを読むことがあります。 1000個のインサートごとに。これはいくつかの理由で悪いアドバイスであり、すべてがトランザクションに関連するわけではありません。関連するものは次のとおりです。
- コミットを発行すると、リソースのロックが解放されます。これが
ORA-1555 Snapshot too old
のエラーの原因です。
- また、文やトランザクション・レベルでのみ適用される読取り一貫性にも影響します。これは
ORA-1002 Fetch out of sequence
というエラーの原因です。
- 再始動性に影響します。プログラムが30%のレコードを処理できなかった場合、バッチを再実行すると残りの70%のみが処理されると確信できますか?
- レコードがコミットされると、他のセッションでこれらの変更が表示される可能性があります。他のユーザーが部分的に変更したデータビューを参照するのは意味がありますか?
したがって、「Oracleの知恵」とは、作業単位ごとに1回のコミットでデータベーストランザクションとビジネストランザクションを常に整列させることです。
誰かがサブプロセスにコミットを発行する方法としてautonmous transactionsを挙げます。これは通常、悪い考えです。自律型トランザクションで行われた変更は、他のセッションでは表示されますが、自社のものでは表示されません。それはまれには意味をなさない。それはまた、私が前に議論した再起動性と同じ問題を引き起こす。
自動トランザクションで使用できるのは、記録アクティビティ(エラーログ、トレース、監査レコード)のみです。幅広いトランザクションで何が起こっても、そのデータを保持する必要があります。プラグマを他の方法で使用することは、確かに問題を悪化させるporrデザインの回避策です。
出典
2012-03-29 11:55:14
APC
あなたの問題は、私たちに示していないコード、LOADER自体にあります。何らかの理由で、仕事の状態の変化を拾っていない。その理由はいくつかありますが、コードを見ずに提案をするのは難しいです。 – APC
"* call loader *"は正確に何をしますか? –
'loader'がなくても、(a)あなたの' procedure CreateWorkUnit'コード断片が不明です:それは無名ブロック内か、 'CREATE'コマンドの前にありますか? (b) 'CreateWorkUnit'がまったく実行されていることをどのように知っていますか? (c) 'END'が欠落しています。 –