![](/img/trans.png)
[英]Use ExecutorService or Similar to Queue Tasks to be Completed in Order?
[英]use database as a queue of tasks
在我们的一个Java应用程序(基于postgresql db)中,我们有一个数据库表,该表维护着要执行的任务列表。 每行都有一个json blob,用于显示任务的详细信息以及计划的时间值。
我们有一些Java工作程序/线程,其工作是搜索准备好执行的任务(基于其计划值),执行该任务并将其从表中删除。 执行任务可能需要几秒钟。
问题是,一个以上的工人可能会抓住同一行,从而导致重复执行任务,这是我们要避免的事情。
一种方法是,在执行select
抓取一行时,使用FOR UPDATE
来锁定该行,以防止其他工作程序抓取被锁定的同一行。
我对这种方法的担心是,仅当在db中执行select
事务时,行才被锁定(根据this ),而Java代码实际上正在执行所选的行/任务时,锁定已消失,另一位工作者可以再次抓住它。
是否可以确定上述方法是否一定行得通? 谢谢!
将DB调用视为原子指令,并使用更新将布尔值列“进行中”的布尔值从false更改为true,从而在表周围设计无锁算法。 也可能只是一个state int
(0 =可用,1 =进行中,N =结果代码)。
确保在状态0上有部分索引(可能从崩溃中恢复以找到正在执行的任务的状态为1),以便...where state=0
保持选择性和快速(当然是在计划的时间索引之上) 。
希望这可以帮助。
当一个线程已成功锁定给定连接上的行时,另一线程尝试获得另一连接上的行上的锁应该失败。 如果该行被锁定,则应发出带有某种no-wait子句的select-for-update,以请求立即失败。
现在,这不能解决查询与锁竞争,因为失败的锁可能会中断线程的执行。 您可以通过以下方式解决此问题:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.