我有一个rails应用程序,我故意崩溃..它是本地的,我只是按ctrl + c并在处理记录中途杀死它..
在我看来,块中的记录不应该被提交。这是postgres“error”还是rails“error”,还是dave ERROR?
ActiveRecord::Base.transaction do
UploadStage.where("id in (#{ids.join(',')})").update_all(:status => 2);
records.each do |record|
record.success = process_line(record.id, klas, record.hash_value).to_s[0..250]
record.status = 1000
record.save();
end
end
我通过读出状态为1的所有记录来生成我的ID 除此功能外,只有状态设置为1000 ..
如果动作因任何原因崩溃,我希望数据库中没有状态= 2的记录...... 这不是我所看到的。一半记录的状态为1000,另一半的状态为2 ..
我错过了什么吗? 如果应用程序崩溃,如何确保没有2?
答案 0 :(得分:1)
正如我怀疑并且正如dave的更新所证实的那样,当你杀死一个线程时,看起来ActiveRecord会在某些情况下提交一个半成品事务。哇,安全!有关详细说明和缓解选项,请参阅dave's link。
如果您正在模拟硬崩溃(主机操作系统崩溃或插件拉动),那么control-C绝对不是正确的方法。使用Control-\
发送SIGQUIT
(通常不会处理),或使用kill -KILL
来强制删除进程而无法进行清理。 Control-C
发送SIGINT
这是一个温和的信号,通常附加到干净的关机处理程序。
通常,如果您正在调试此类问题,则应启用详细的查询日志记录并查看Rails正在执行的操作。在log_statement = 'all'
中使用postgresql.conf
,然后检查PostgreSQL日志。