0

たとえば、Rails3.2.3にコードがあるとします。

def test_action
  a = User.find_by_id(params[:user_id])
  # some calculations.....
  b = Reporst.find_by_name(params[:report_name])
  # some calculations.....
  c = Places.find_by_name(params[:place_name])
end

このコードは、データベースに対して3つのリクエストを実行し、3つの異なる接続を開きます。ほとんどの場合、それはかなり長いアクションになるでしょう。

1つの接続のみを開き、その中で3つの要求を行う方法はありますか?または、使用する接続を自分で制御したい。

4

2 に答える 2

1

ActiveRecord::ConnectionAdapters::ConnectionPoolのドキュメントを参照してください。また、AR はモデル/クエリごとに接続を開かず、既存の接続を再利用します。

[7] pry(main)> [Advertiser.connection,Agent.connection,ActiveRecord::Base.connection].map(&:object_id)
=> [70224441876100, 70224441876100, 70224441876100]
于 2012-08-08T09:17:12.097 に答える
1

呼び出しをtransaction次のように囲みます。

トランザクションは保護ブロックであり、SQL ステートメントはすべて 1 つのアトミック アクションとして成功する場合にのみ永続的になります。古典的な例は、引き出しが成功した場合にのみ預金を持つことができる 2 つの口座間の送金であり、その逆も同様です。トランザクションは、データベースの整合性を強化し、プログラム エラーやデータベースの故障からデータを保護します。したがって、基本的に、一緒に実行する必要がある、またはまったく実行しないステートメントが多数ある場合は、トランザクション ブロックを使用する必要があります。

def test_action
  User.transaction do
    a = User.find_by_id(params[:user_id])
    # some calculations.....
    b = Reporst.find_by_name(params[:report_name])
    # some calculations.....
    c = Places.find_by_name(params[:place_name])
  end
end

それらは異なるモデルを呼び出しますが、アクションは DB への 1 つの呼び出しにカプセル化されます。しかし、それはすべてか無かです。1 つが途中で失敗すると、カプセル全体が失敗します。

トランザクション クラス メソッドは Active Record クラスで呼び出されますが、トランザクション ブロック内のオブジェクトがすべてそのクラスのインスタンスである必要はありません。これは、トランザクションがモデルごとではなく、データベース接続ごとであるためです。

于 2012-08-08T09:17:52.590 に答える