SQL For Update Skip Locked Query和Java Multi Threading - 如何解决这个问题

jun*_*sal 2 sql oracle concurrency locking oracle11g

SELECT 
        id
        FROM table_name tkn1,
        (SELECT 
            id, 
            ROWNUM rnum
         FROM table_name 
         WHERE 
            PROCS_DT is null
         order by PRTY desc, CRET_DT) result 
        WHERE  tkn1.id= result.id
        AND result.rnum <= 10 FOR UPDATE OF tkn1.id SKIP LOCKED
Run Code Online (Sandbox Code Playgroud)

这是我的问题.2个线程同时访问此查询

线程1 - 执行选择并锁定按降序优先级和创建日期排序的10行.接下来,我将从单独的查询中将procs_dt更新为今天的日期.

线程2 - 在更新procs_dt或从线程1发生提交之前,此线程执行此查询.我的要求是接下来的10个未锁定的行必须移交给线程2.但是真正发生的是同一组锁定的行来自内部查询,因为procs_dt仍为null并且尚未被线程1更新并且因为跳过在外部查询中给出了锁定,所有这10行都被跳过,并且没有返回任何记录供线程2处理

这最终打败了我的多线程要求.

如何解决此问题?我尝试添加锁定到内部查询的跳过.但是oracle 11g不允许它.

专家请帮忙.我正在使用oracle 11g

Gar*_*ers 5

我会用这样的东西:一个光标来选择行以便更新,并使用LIMIT子句来获得前十个.

create table gm_temp
as select rownum id, table_name obj_name, date '2011-01-01' + rownum create_date 
from all_tables where rownum < 500;

CREATE TYPE tab_number IS TABLE OF NUMBER;

DECLARE
  cursor c_table IS 
    SELECT id FROM gm_temp ORDER BY create_date DESC FOR UPDATE OF id SKIP LOCKED;
  t_table_src tab_number := tab_number();
BEGIN
  OPEN c_table;
  FETCH c_table BULK COLLECT INTO t_table_src LIMIT 10;
  CLOSE c_table;
  dbms_output.put_line(':'||t_table_src.count||':'||t_table_src(1));
END;
Run Code Online (Sandbox Code Playgroud)

实际上,我首先要看看将所有未完成的行作为一组进行处理会比多线程更好.

然后,如果我确定我需要某种形式的多线程,我会看一下并行启用的流水线函数(假设我在Enterprise Edition上).