activerecord-import gem如何处理并发导入?它会锁定桌子吗?

时间:2013-03-24 20:12:42

标签: ruby-on-rails

每当有人将股票添加到其投资组合时,我都会使用activerecord import gem来导入股票价格历史记录。在添加股票价格历史记录之前,该函数首先检查表格中是否已存在该股票。这样,即使有2人拥有Google股票,它也不会两次填充股票价格历史。

然而,这让我想到了并发添加。如果2个人同时添加了Google并且模型中尚未存在价格历史记录,则函数“import”会同时发生两次。

这让我想到了我的问题。 activerecord-import是否锁定表以防止同时进行2次导入?

编辑:根据Jim的建议,我做了以下工作:

在我的Stock模型中,我使用after_save运行一个导入StockHistory的函数,所以我锁定了StockHistory:

def populatepricehistory

#columns and prices defined here

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

1 个答案:

答案 0 :(得分:1)

activerecord-import本身没有显式锁定。如果您正在使用并发性做任何事情,最好明确地隔离事物。将您的更新换成ActiveRecord transaction。您还可以更明确地使用ActiveRecord的pessimistic locking机制进行锁定,但这在大多数情况下并不是必需的。最好让其中一个交易失败并处理失败。

在交易中包装非常简单:

# 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数组。

查看上面的两个链接了解详情。