0

誰かがポートフォリオに株式を追加するたびに、activerecordimportgemを使用して株価履歴をインポートします。株価履歴を追加する前に、関数はまずその株式がテーブルにすでに存在するかどうかをチェックします。そうすれば、2人がGoogleの株を持っている場合でも、株価履歴に2回入力されることはありません。

しかし、これは私に同時追加を考えさせました。2人が同時にGoogleを追加し、価格履歴がモデルにまだ存在していなかった場合、関数'import'は同時に2回発生します。

それは私の質問に私をもたらします。activerecord-importは、同時に2つのインポートを防ぐためにテーブルをロックしますか?

編集:ジムのアドバイスに基づいて、私は以下を行いました:

私のStockモデルでは、を使用しafter_saveてStockHistoryにインポートする関数を実行しているため、StockHistoryを次のようにロックします。

def populatepricehistory

#columns and prices defined here

StockHistory.transaction do
    StockHistory.lock
    StockHistory.import columns,prices
end
4

1 に答える 1

1

activerecord-import明示的なロック自体は行いません。並行性を使って何かをしている場合は、物事を明示的に分離するのが最善です。更新をActiveRecordトランザクションでラップします。ActiveRecordの悲観的なロックメカニズムを使用してロックすることについてより明確にすることもできますが、それはほとんどの場合必要ではありません。多くの場合、トランザクションの1つを失敗させて、失敗を処理する方がよいでしょう。

トランザクションのラッピングは簡単です。

# Inside ActiveRecord model Foo:

def some_bulk_update
  foo_records = generate_some_foo_records()
  transaction do
    self.import foo_records
  end
end

競合のウィンドウを減らすために、トランザクションの外部でできる限り多くのことを行うことをお勧めします。 上記は、インポートgenerate_some_foo_records()する配列を構築するためにトランザクションの前にメソッドを呼び出す方法の単なる例です。foo_records

詳細については、上記の2つのリンクを確認してください。

于 2013-03-24T20:26:12.640 に答える