3

わざとクラッシュしている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に設定しません。

なんらかの理由でアクションがクラッシュした場合、データベースにステータス=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/

4

1 に答える 1

1

私が疑ったように、そしてdaveの更新によって確認されたように、スレッドを強制終了すると、ある状況下でActiveRecordが途中で終了したトランザクションをコミットするように見えます。ウー、安全!詳細な説明と軽減オプションについては、 daveのリンクを参照してください。

ハードクラッシュ(ホストOSのクラッシュまたはプラグプル)をシミュレートしている場合、control-Cは絶対に正しいアプローチではありません。通常は処理されないControl-\を送信するために使用するか、クリーンアップを実行する機会がないプロセスをハードキルするために使用します。これは、通常、クリーンなシャットダウンハンドラーに接続される穏やかなシグナルです。SIGQUITkill -KILLControl-CSIGINT

一般に、このような問題をデバッグしている場合は、詳細なクエリログを有効にして、Railsが何をしているかを確認する必要があります。で使用log_statement = 'all'してpostgresql.confから、PostgreSQLログを調べます。

于 2012-12-12T00:25:16.313 に答える