関数/手順でDML操作後にコミットが必要ですか?
-
22-10-2019 - |
質問
関数/手順で挿入/削除/更新後にコミットを書く必要があるかどうかを知りたいですか?
例:
create or replace function test_fun
return number is
begin
delete from a;
return 0;
end;
または手順
create or replace procedure aud_clear_pro
as
begin
delete from a;
end;
削除後にコミットが必要ですか?
次の状況を理解できません:
SQLウィンドウから関数/手順を呼び出すと、コミットが必要です
しかし
dbms_schedulerを使用して関数/手順をスケジュールしてジョブを実行すると、削除ステートメントが自動的にコミットされます。
なぜ?
解決
一般に、手順はコミットすべきではありません。これらの種類のトランザクション制御の決定は、論理トランザクションが実際に完了したことを知っている高レベルのコードに任せる必要があります。ストアドプロシージャの内部でコミットする場合、手順が大規模なトランザクションの一部であるようにする変更を望んでいる発信者は、単に手順を直接呼び出すことができないため、その再利用性を制限しています。
手順をインタラクティブに呼び出す場合、Oracleが論理トランザクションであることを意図しているか、複数の手順コールを含むより大きなトランザクションを作成する予定かどうかをOracleが知らないため、トランザクションを明示的にコミットまたはロールバックする必要があります。使用する場合 dbms_scheduler
, dbms_scheduler
仕事は論理的な取引であり、成功したと仮定して、仕事の終わりにコミットすると仮定します(dbms_job
同じことをします)。
関数は、そもそもデータを操作しないでください。データを操作する関数は、SQLステートメントから呼び出すことはできません(関数自体がほとんど適切ではない自律的なトランザクションを使用すると宣言されているコーナーケースを除く)。関数と手順の両方を持っていることの全体的なポイントは、関数をSQLステートメントに埋め込み、データを変更しないためユーザーにより自由に付与できることです。
他のヒント
あなたの質問に答えるために;なぜ?
投稿は2歳なので、おそらく今までにこれを知っているでしょう。しかし、私は記録のためだけに応答します。
#1がコミットを必要とする理由は、#2ではないため、Oracleのデフォルトのデータベース設定は、セッションが終了したときにトランザクションをコミットすることであるためです。 sqlplusにいて、コードを手動で実行している場合、すぐにトランザクションをコミットしません。明示的なコミットを発行したり、SQLPUSからログオフすると、トランザクションがコミットされます。
#2で自動コミットを取得する理由は、スクリプトを実行するセッションを作成するためです。完了すると、自動的にログオフされ、自動コミットが発生します。