与Run rails code after an update to the database has commited, without after_commit相关,但我认为值得提出自己的问题。
如果我有这样的代码:
my_instance = MyModel.find(1)
MyModel.transaction do
my_instance.foo = "bar"
my_instance.save!
end
new_instance = MyModel.find(1)
puts new_instance.foo
这是保证 new_instance.foo
将始终输出“bar”而不是之前的值吗?我正在寻找一种方法来确保在执行我的下一个语句之前提交先前语句中发生的所有数据库操作。 Rails有一个after_commit钩子,但我不想每次都执行这个代码......只在这个特定的上下文中。
我在关于事务的文档中找不到任何指示Transaction块是否“阻塞”的内容。如果他们阻止,那将满足我的要求。不幸的是,我想不出一种切实可行的方法来测试这种行为,以某种方式证实我的怀疑。
答案 0 :(得分:3)
仍在研究这个问题,但我认为事务会阻止代码执行,直到数据库确认已写入。自“拯救!”由Rails自动包装在事务中,相关代码应该同步运行。额外的交易块应该是不必要的。
当数据库调用在事务中时,我不认为Rails一旦发出数据调用就会返回。我遇到的困惑是after_save回调。 After_save回调受竞争条件的影响,因为它们实际上是保存的事务的一部分被自动包装,因此after_save回调调用的任何代码都不是竞争条件安全的,它不受事务保护。只有after_commit调用是安全的。在事务中,Rails将切换到DB,然后在DB完成提交之前执行after_save回调。
研究这个以获得更多见解:
更新
将我的回答改为“否”。它似乎没有保存!或保存块执行。从这两个资源看起来这是一个常见的问题: