问题:rails activerecord 事务块似乎没有提交

我有一个我故意崩溃的rails应用程序..它是本地的,我只是按ctrl + c并在处理记录的中途杀死它..

在我看来,不应该提交块中的记录。这是 postgres“错误”还是 rails“错误”,还是 dave 错误?

      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..

如果操作因任何原因崩溃,我希望数据库中没有状态 u003d 2 的记录......但这不是我所看到的。一半的记录状态为 1000,另一半的状态为 2...。

我错过了什么吗?

如果应用程序崩溃,我如何确保没有 2?


编辑:

我找到了这个链接http://coderrr.wordpress.com/2011/05/03/beware-of-threadkill-or-your-activerecord-transactions-are-in-danger-of-being-partially-committed/

解答

正如我所怀疑的那样,正如 dave 的更新所证实的那样,在某些情况下,当你杀死一个线程时,ActiveRecord 似乎会提交一个半完成的事务。哇,安全!有关详细说明和缓解选项,请参阅dave 的链接。

如果您正在模拟硬崩溃(主机操作系统崩溃或插拔),那么 control-C 绝对不是正确的方法。使用Control-\发送一个SIGQUIT,一般不处理,或者使用kill -KILL硬杀进程,没有机会做清理。Control-C发送SIGINT这是一个温和的信号,通常附加到一个干净的关闭处理程序。

一般来说,如果你正在调试这样的问题,你应该启用详细的查询日志并查看 Rails 正在做什么。在postgresql.conf中使用log_statement = 'all'然后检查 PostgreSQL 日志。

Logo

PostgreSQL社区为您提供最前沿的新闻资讯和知识内容

更多推荐