读取数据库表的一行上的锁定

时间:2013-11-01 12:26:12

标签: mysql sql ruby-on-rails cron locking

我正在尝试构建一个作业调度程序。我有一个作业列表,可以按时在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。它可以解决问题。如果存在......语法是什么?

1 个答案:

答案 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个线程运行相同的任务。

相关问题