例如,假设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个请求?或者我想控制自己使用哪个连接。
答案 0 :(得分:1)
您可以查看ActiveRecord::ConnectionAdapters::ConnectionPool文档 此外,AR不会为每个模型/查询打开连接,它会重用现有连接。
[7] pry(main)> [Advertiser.connection,Agent.connection,ActiveRecord::Base.connection].map(&:object_id)
=> [70224441876100, 70224441876100, 70224441876100]
答案 1 :(得分: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
即使他们调用不同的模型,操作也会封装到对DB的一次调用中。虽然它是全有或全无。如果中间失败则整个胶囊失效。
虽然在某些Active Record上调用了事务类方法 class,事务块中的对象不一定都是 该类的实例。这是因为事务是按数据库进行的 连接,而不是每个模型。