Bri*_*ian 10 postgresql ruby-on-rails resque ruby-on-rails-3
我正在尝试与我的后台任务经理对抗一些种族案件.基本上,我有一个Thing
对象(已经存在)并为其分配一些属性,然后保存它.使用新属性保存后,我将其排入Resque,并传入ID.
thing = Thing.find(1)
puts thing.foo # outputs "old value"
thing.foo = "new value"
thing.save
ThingProcessor.queue_job(thing.id)
Run Code Online (Sandbox Code Playgroud)
后台作业将使用从数据库加载对象Thing.find(thing_id)
.
问题是我们发现Resque在获取作业和Thing
从ID 加载对象方面非常快,它加载了一个陈旧的对象.因此,在工作中,调用thing.foo
仍将返回"旧值",如1/100次(不是真实数据,但不会经常发生).
我们知道这是一个竞争案例,因为rails将thing.save
在数据实际提交到数据库之前返回(在本例中为postgresql).
Rails中有一种方法只能在数据库操作提交后执行代码吗?基本上我想确保在Resque加载对象时,它会获得最新鲜的对象.我知道这可以使用模型after_commit
上的钩子来实现Thing
,但我不希望它在那里.我只需要在这个特定的上下文中发生这种情况,而不是每次模型都提交更改为DB时.
您也可以进行交易.就像下面的例子:
transaction do
thing = Thing.find(1)
puts thing.foo # outputs "old value"
thing.foo = "new value"
thing.save
end
ThingProcessor.queue_job(thing.id)
Run Code Online (Sandbox Code Playgroud)
更新:有一个调用After Transaction的gem,你可以解决这个问题.这是链接:http: //xtargets.com/2012/03/08/understanding-and-solving-race-conditions-with-ruby-rails-and-background-workers/
归档时间: |
|
查看次数: |
2112 次 |
最近记录: |