在我的rails应用程序中,我有一些类似以下的代码:
def foo
if object_bar_exists
raise "can't create bar twice!"
end
Bar.create
end
可以由进入应用程序服务器的两个不同请求来调用。如果此代码同时由两个请求运行,并且它们都同时运行
if
检查,则两个都不会找到对方的bar
,并且将创建2个bar
。为“酒吧集合”创建“互斥体”的最佳方法是什么?数据库中有特殊用途的互斥表?
更新
我要强调的是,我不能在这里使用内存互斥锁,因为并发是跨请求/进程而不是线程的。
最佳答案
最好的办法是在数据库事务中执行操作。因为您最终可能会运行多个应用程序,并且它们很可能不会共享内存,所以您将无法在应用程序级别上创建Mutex锁,尤其是当这两个应用程序服务在完全不同的物理设备上运行时。这是完成数据库事务的方法:
ActiveRecord::Base.transaction do
# Transaction code goes here.
end
如果要确保对数据库事务进行回滚,则必须在Bar类上启用验证,以便无效的保存请求将导致回滚:
ActiveRecord::Base.transaction do
bar = Bar.new(params[:bar])
bar.save!
end
如果数据库中已经有条形对象,则可以这样悲观地锁定该对象,如下所示:
ActiveRecord::Base.transaction do
bar = Bar.find(1, :lock => true)
# perform operations on bar
end
关于ruby-on-rails - 如何锁定一组对象以进行操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5424322/