2

Rails 3.1.3 アプリで 2 つのテーブルに保存するために、out_logs コントローラーに次のコードがあります。2 つの節約が完了またはなしで行われることを確認するために、トランザクションが使用されます。

  @out_log.transaction do
    if @out_log.save && @part.save
      redirect_to part_path(@part), :notice => "Saved!"
    else
      flash.now[:error] = "Not saved!"
      render 'new'
    end   
  end  

コードは機能しているようです。私たちの質問は次のとおりです。

  1. 上記のコードはトランザクションの良い方法ですか?
  2. トランザクション ループには、redirect_to と render があります。これらの redirect_to または render は、トランザクション ループの実行時間を増やし、データベース (sqlite3 を使用) を長時間ロックしますか?

本当にありがとう。

4

1 に答える 1

3

最初に:redirect_toまたはステートメントrenderのように振る舞わないでください。return現在準備中の応答にいくつかのヘッダーを割り当てるだけです。

お取引について:

if @out_log.save && @part.save

上記のコードは、DB 内で一貫性のない状態につながることは間違いsaveありません。最初のコードが成功し、2 番目のコードが成功しなかった場合 想像するのさえ難しいです。

解決策は非常に簡単です: save!(最後に感嘆符を付けて) を使用します。このようにして、検証が失敗した場合、トランザクション全体がロールバックされます (save!が返す代わりに、によって例外が発生falsesaveます)。

于 2012-04-22T13:02:33.817 に答える