私は、Oracle がどのように処理するかという問題に対処しようとしてきましROWNUM
たSELECT ... FOR UPDATE SKIP LOCKED
が、ロックされていないいくつかの行を返そうとしています。私は次のいくつかの解決策を試しました: Oracle に SKIP LOCKED を使用して TOP N 行を返すように強制する、およびその質問で見つかったものと非常によく似た他のいくつかの例。Oracle AQ がおそらくこれに対する最善の解決策であることはわかっていますが、データベースをほとんど制御できず、このアイデアに対するかなりの抵抗に遭遇しました。
私が直面している問題は、JDBC を使用して結果を Java に戻そうとすることです。を試しsetFetchSize(20)
ましたが、上位 20 行のみがクライアントに配布されるという問題が発生しました。通常、1 つの処理エージェントが 20 行すべてを取得するか、いくつかのプロセッサがいくつかの行を取得し、すべての行を合計すると 20 になりROWNUM
ますSELECT ... FOR UPDATE SKIP LOCKED
。
私が試した最も有望な解決策は、次の機能です。
create type IND_ID as object
(
ID varchar2(200)
);
create type IND_ID_TABLE as table of IND_ID;
create or replace function SELECTIDS return IND_ID_TABLE
pipelined is
ST_CURSOR SYS_REFCURSOR;
ID_REC IND_ID := IND_ID(null);
begin
open ST_CURSOR for
select ID
from TABLE
/* where clause */
for update SKIP LOCKED;
loop
fetch ST_CURSOR
into ID_REC.ID;
exit when ST_CURSOR%rowcount > 20 or ST_CURSOR%notfound;
pipe row(ID_REC);
end loop;
close ST_CURSOR;
return;
end;
ただし、次のように呼び出してみると:
select * from table(SELECTIDS)
エラーが発生しましたORA-14551: cannot perform a DML operation inside a query
が、これはトランザクションの問題であることがわかりました。ロックを解除すると、関数は行を返します。
ロックを保持しながら、この関数から複数の行を JDBC に取得するにはどうすればよいですか?