0

我正在尝试构建一个作业调度程序。我有一个要在 2-3 台不同机器上按时间执行的作业列表。所以任何机器都可以选择任何工作,如果它的next_execution_time < current_time. 我将所有作业存储在数据库表中,并使用SELECT.... FOR UPDATESQL 中的查询来选择要执行的作业。

但是这种方法的问题是,如果一台机器1选择了一个作业,由于只有写锁,其他机器也会选择相同的作业执行,但不能执行,因为它们会等待锁定释放或锁定超时将发生。那么有什么办法让其他机器跳过这个作业并使用 SQL 锁执行其他作业。不应该在数据库中添加其他列?

流程是这样的:

select a job and lock it -> execute the job -> release the lock

我正在使用 ruby​​-on-rails 来开发它。如果 rails 中没有等待或 set_lock_timeout = 0。它可能可以解决问题。如果存在......语法是什么?

4

1 回答 1

0

实际上,您有一个简单的方法可以对 mysql 中的当前表执行此操作,您需要在选择下一个任务时临时锁定该表。我假设您在表中有一个列来标记已经开始/完成的任务,否则您可以使用与日期时间相同的列来启动作业来标记它已经完成/开始:

lock tables jobs write;

select * from jobs where start_time < current_time and status = 'pending' order by start_time;
-- be carefull here to check for SQL errors in your code and run unlock tables if an exception is thrown or something like that

update jobs set status = 'started' where id = the_one_you_selected_adobe;

unlock tables;

就是这样,多个并发线程/进程 cab 使用作业表来执行任务,而无需 2 个线程运行相同的任务。

于 2013-11-01T18:40:16.970 回答