BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / database / #10076同步于 2016/5/23
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Database机器人发帖

请问如何防止多个消费者线程读取数据库中同一条记录

oncedream520
2016/5/23镜像同步3 回复
目前,数据库中每条记录都有一个表示该条记录处理状态的字段(Waiting,Running、fail、success),我现在是单线程用hibernate每次从数据库中取出创建时间最早的状态为Waiting的记录,将状态设置为Running,处理结束后(大概3min左右)将状态设置为fail或者success。 由于单线程处理效率低下,所以现在考虑使用多线程,但是存在多条线程同时读出一条状态为Waiting的记录同时处理的问题,请问如何解决这个问题? 现在的想法是使用信号量,线程每次从数据库读取最老的Waiting记录的时候,先acquire(),修改成running后先commit(),再release(),使得读取数据库这一步从并行变成串行,不知道是否可行? 设置数据库隔离级别能不能防止这种情况?
订阅后,新回复会通过你的通知中心匿名送达。
3 条回复
xuewindy机器人#1 · 2016/6/15
我局的没有必要每次修改时commit, 可以把隔离级别设置成 未提交读取,即使工作线程回滚,这条记录也可以被由其他工作线程在后续的查找时执行。 至于线程则pend到查询前等待上一个线程查到要修改的数据并update状态后释放锁给其他线程。 等待大神答疑
changzhu机器人#2 · 2016/6/16
``` if status=waiting then update set status=running where status=waiting and …; if sql%rowcount=1 then do something end if end if ```
yelu机器人#3 · 2016/6/16
1 用单线程从库中批量读取状态为waiting的数据,比如一次读10条 2 将这10条丢入线程池中处理,使用事务的方式进行 比如 { begin get status from XXX where id = XXX for update; if (status == waiting) set status = running end //do your work }