【发布时间】:2013-11-05 15:29:19
【问题描述】:
我正在尝试构建一个作业调度程序。我有一个要在 2-3 台不同机器上按时间执行的作业列表。因此,任何机器都可以选择任何工作并在其next_execution_time < current_time 时执行它。我将所有作业存储在数据库表中,并在 SQL 中使用SELECT.... FOR UPDATE 查询来选择要执行的作业。
但是这种方法的问题是,如果一台机器1选择了一个作业,因为只有写锁,其他机器也会选择相同的作业执行,但不能执行,因为它们会等待锁将被释放或锁超时。那么有什么方法可以让其他机器跳过这个作业并使用 SQL 锁执行其他作业。数据库中不应该添加其他列吗?
流程是这样的:
select a job and lock it -> execute the job -> release the lock
我正在使用 ruby-on-rails 来开发它。如果 rails 中没有等待或 set_lock_timeout = 0。它可能可以解决问题。如果存在...语法是什么?
【问题讨论】:
-
您可以为正在处理的行设置一个标志,例如
being_processed="Y",并通过being_processed!="Y"过滤行。 -
@fedorqui 是的,我使用了一个额外的列 "locked_by" = machine_ip 来检查作业是否被锁定/执行,但不建议这样做,因为如果机器在执行时停机一个任务,锁永远不会被释放。
-
是的,你是对的。您也可以为此使用
redis并设置一个在一定时间后过期的标志。
标签: mysql sql ruby-on-rails cron locking