小编典典

SQL for Update跳过锁定查询和Java多线程-如何解决此问题

sql

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

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

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

线程2-在从线程1更新procs_dt或commit之前,此线程执行此查询。我的要求是必须将下10个未锁定的行移交给线程2。但是实际上发生的是同一组锁定行从内​​部查询中出来,因为procs_dt仍然为null,并且尚未由线程1进行更新,并且由于跳过在外部查询中给出了locked,所有这10行都被跳过,没有记录返回给线程2处理

这最终违反了我的多线程要求。

如何解决此查询?我尝试将锁定的跳过添加到内部查询中。但是oracle 11g不允许这样做。

高手请帮忙。我正在使用oracle 11g


阅读 201

收藏
2021-04-07

共1个答案

小编典典

我将使用这样的方法:游标选择行以进行更新,并使用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;

实际上,我首先要看看将所有未完成的行作为一个集合进行处理是否比多线程处理要好。

然后,如果确实确定我需要某种形式的多线程,那么我将研究启用了并行功能的流水线函数(假设我使用的是Enterprise Edition)。

2021-04-07