0

例如,假设 Rails 3.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 个不同的连接。很可能这将是一个相当长的动作。

有没有办法只打开一个连接并在其中执行 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 语句只有在它们都可以作为一个原子操作成功时才​​是永久的。典型的例子是两个账户之间的转账,如果取款成功,您只能进行存款,反之亦然。事务强制执行数据库的完整性并保护数据免受程序错误或数据库故障的影响。因此,基本上,只要您有许多必须一起执行或根本不执行的语句,您就应该使用事务块。

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

即使它们调用不同的模型,操作也被封装到对数据库的一次调用中。要么全有,要么全无。如果一个在中间失败,那么整个胶囊就会失败。

尽管在某些 Active Record 类上调用了事务类方法,但事务块中的对象不必都是该类的实例。这是因为事务是每个数据库连接的,而不是每个模型的。

于 2012-08-08T09:17:52.590 回答