一、场景一
一个表有几百万条数据要处理,处理完的记录改为已处理。
1、分析
这种情况因为状态是在一个表中的,所以可以用阻塞队列的模式
2、解决方案
1、生成者线程从每次从表中获取一批未处理的数据,修改状态为处理中,然后一条条记录加到固定大小的阻塞队列中。因为如果队列满了则程序会阻塞在这里,如果数据为空,则休息一分钟。
2、消费者则启动多个线程从阻塞队列中获取内容来处理即可。处理完后把状态改为已处理。
二、场景二
一个表有几百万条数据要处理,但是表中没有处理状态,只能用新的明细表来保存处理状态。
1、分析,这种情况因为不是同一个表,但是也是可以用阻塞队列的模式。
所以查询一批未处理的数据的sql可能要用如下的场景:
2、解决方案
1、生成者线程从每次从表中获取一批未处理的数据,插入明细表中,然后一条条记录加到固定大小的阻塞队列中。因为如果队列满了则程序会阻塞在这里,如果数据为空,则休息一分钟。
2、消费者则启动多个线程从阻塞队列中获取内容来处理即可。处理完后把状态改为已处理。
跟第一种情况的区别只是获取一批未处理的数据的方法区别,要用在A表不在B表的查询模式。
SELECT * FROM A WHERE (SELECT COUNT(1) AS num FROM B WHERE A.a_id=B.b_id)=0 and rownum<=N
三、总结
这两种方案因为都是提前修改状态,或者提前插入明细表,所以可能会导致有些数据没处理成功,所以要有个定时任务把场景一处理了很久还是处理中的改为未处理,把场景二的明细表中状态为待处理的删除。