我正在尝试构建一个作业调度程序。我有一个作业列表,可以按时在2-3台不同的机器上执行。因此,任何机器都可以选择任何作业,并且如果next_execution_time < current_time
将执行它。我将所有作业存储在数据库表中,我在SQL中使用SELECT.... FOR UPDATE
查询来选择要执行的作业。
但是这种方法的问题在于,如果机器1选择了一个作业,由于只有写锁定,其他机器也会选择相同的作业执行,但无法执行,因为它们会等待锁定被释放或锁定超时将发生。那么有没有办法让其他机器跳过这个工作并使用SQL锁执行其他工作。数据库中不应该添加其他列吗?
Flow就像这样:
select a job and lock it -> execute the job -> release the lock
我正在使用ruby-on-rails来开发它。如果rails中没有等待或set_lock_timeout = 0。它可以解决问题。如果存在......语法是什么?
答案 0 :(得分:0)
实际上你有一个简单的方法用mysql中的当前表做这个,你需要在选择下一个任务时暂时锁定表。我假设您在表中有一列标记已经启动/完成的任务,否则您可以使用与datetime相同的列来启动作业以标记它已经完成/已启动:
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使用jobs表来执行任务,而没有2个线程运行相同的任务。