在更新数据库提交后运行rails代码,没有after_commit
我正在尝试与我的后台任务经理对抗一些种族案件。 基本上,我有一个Thing
对象(已经存在)并为其分配一些属性,然后保存它。 使用新属性保存后,我将其排入Resque,并传入ID。
thing = Thing.find(1) puts thing.foo # outputs "old value" thing.foo = "new value" thing.save ThingProcessor.queue_job(thing.id)
后台作业将使用Thing.find(thing_id)
从数据库加载对象。
问题是我们发现Resque在获取作业和从ID加载Thing
对象方面非常快,它加载了一个陈旧的对象。 因此,在工作中,调用thing.foo
仍将返回“旧值”,如1/100次(不是真实数据,但它不会经常发生)。
我们知道这是一个竞赛案例,因为在数据实际提交到数据库之前 ,rails将从thing.save
返回(在本例中为postgresql)。
Rails中有一种方法只能在数据库操作提交后执行代码吗? 基本上我想确保在Resque加载对象时,它会得到最新鲜的对象。 我知道这可以使用Thing
模型上的after_commit
钩子来实现,但我不想在那里。 我只需要在这个特定的上下文中发生这种情况,而不是每次模型都提交更改为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)
更新:有一个调用After Transaction的gem,你可以解决这个问题。 这是链接: http : //xtargets.com/2012/03/08/understanding-and-solving-race-conditions-with-ruby-rails-and-background-workers/
如果围绕transaction
进行try
,那么只有在事务成功时才将作业排队?
- 时间戳无法保存 – postgresql
- Rails范围在月内创建
- Ruby中DateTime的毫秒分辨率
- 我无法将我的rails应用程序推送到Heroku /获取’pg’gem安装?
- 为什么我的Rails 4 / Postgres中的所有表都以1的“维度”创建?
- rails postgres insert
- 错误未定义方法`的to_key’:尝试在Active Admin table_for上使用数组数据时的数组(Rails,Postgresql,postgres_ext gem)
- Rails不转换时区(PostgreSQL)
- 由于未知OID被视为String,ActiveRecord和SQL不会返回相同结果的情况