Ruby on rails 3 Rails并发问题-如何使用锁
我有一个lib类(“Updater”),它可以执行一些长任务,这些任务可以手动(在浏览器中)启动,也可以每2小时启动一次(我已经实现了where gem,它每2小时执行一次计划) 看到这个任务在数据库上做了很多工作,我认为可能会发生一些并发错误(例如,如果调用when还可以工作)。 我说得对吗 我想到了一个使用互斥体的解决方案,为我的更新程序类提供了一个伪代码,如下所示:Ruby on rails 3 Rails并发问题-如何使用锁,ruby-on-rails-3,concurrency,Ruby On Rails 3,Concurrency,我有一个lib类(“Updater”),它可以执行一些长任务,这些任务可以手动(在浏览器中)启动,也可以每2小时启动一次(我已经实现了where gem,它每2小时执行一次计划) 看到这个任务在数据库上做了很多工作,我认为可能会发生一些并发错误(例如,如果调用when还可以工作)。 我说得对吗 我想到了一个使用互斥体的解决方案,为我的更新程序类提供了一个伪代码,如下所示: module Updater def start #do some job end end 我认为,一个正
module Updater
def start
#do some job
end
end
我认为,一个正确的解决方案是这样的
module Updater
def start
mutex.lock
#do some job
mutex.unlock
end
end
我的解决方案正确吗
请提供一些关于并发的更多信息(例如如何在Rails中正确使用互斥,我需要什么,等等)?
我已经搜索过了,但没有找到合理的解释。我认为正确的使用a的方法是获得锁,运行代码块,然后再次释放锁,即结合使用lock和unlock
@mutex = Mutex.new
..
def start
@mutex.lock
begin
..
ensure
@mutex.unlock rescue nil
end
end
或使用同步方法:
@mutex = Mutex.new
..
def start
@mutex.synchronize do
# do something
end
end
可以在Rack Middleware类中找到一个示例。但我不确定它在您的情况下是否有用,即使您使用类变量,如@@mutex
,因为互斥/信号量可能不会在不同的任务和不同的进程之间保留(我假设“任务”是由“rake任务”启动的不同进程)。互斥类对于实现线程安全非常有用,因为它实现了一个简单的信号量,可用于协调对来自多个并发线程的共享数据的访问。然而,也有一个好的(不幸的是,只有在付费墙后面)
在您的情况下,在数据库中创建全局锁标志可能会有所帮助,或者使用
touch lock.txt
在文件系统中创建全局锁文件,并在进程结束时使用rm lock.txt
再次删除该文件。可以使用Kernel.system或%x执行这些命令。如果文件存在file.exists?(“lock.txt”)
则可以暂停更新 +1谢谢你的回答!我将按照您的建议尝试,希望它能与不同的流程协同工作;)