テーブルprocesses
を作成することができます。また、各プロセスにある種の一意の識別子があることも確認してください。たとえば、のプロセスでは、dba_objects
からのowner, object_name
というハッシュがあります。
次に、プロセスが実行されるときにlock each row individuallyに関数を作成します。
@Sergioがコメントで指摘したように、何らかの理由でプロセスの途中でコミットする必要があった場合、各コミット後に再選択しない限り、これはうまくいきません。
function locking (Pid) return number is
l_locked number := 0;
begin
select 1
into l_locked
from processes
where id = Pid
-- exit immediately if the proc is running
for update nowait
;
return l_locked;
exception when others then
return 0;
end;
これは、現在お使いの手順を実行しているセッションが終了するまで、あなたのためprocesses
でその行をロックする利点を有します。
次に、あなたの手順でこれをラップ:
-- if we failed to lock locking will have thrown an error
-- i.e. we have 0 here.
if locking(123) = 0 then
exit;
end if;
限り、それぞれの手順では、固有のIDがあるとして - 重要なビット - あなたの手順が正常に終了しますが。
それはあなたの状況には適用されないかもしれないが、これを行うための私の通常の方法は、mod
を使用することです。同じプロセスを実行している間に2つのプロセスが停止するわけではありませんが、1つ以上のプロセスが異なるデータでのみ実行されるようにします。次のような何か:
procedure my_procedure (PNumerator number, PDenominator number) is
cursor c_my_cursor (CNumerator number, CDenominator number) is
select columns
from my_table
where mod(ascii(substr(id, -1)), CDenominator) = CNumerator
;
begin
open c_my_cursor(PNumerator, PDenominator);
...
end;
出典
2012-03-22 15:42:07
Ben
+1良い質問ですが、 'v $ session'はモジュール上で一意ではないので、間違っている可能性があります。 – Ben
も参照してください。http://stackoverflow.com/questions/1053484/block-procedure-pl-sql-with-oracle – gavenkoa