У меня есть несколько приложений Rails, работающих на одном сервере MySQL. Все они запускают одно и то же приложение, и все базы данных имеют одинаковую схему, но каждая база данных принадлежит отдельному клиенту.
Концептуально, вот что я хочу сделать:
Customer.all.each do |customer|
connection.execute("use #{customer.database}")
customer.do_some_complex_stuff_with_multiple_models
end
Этот подход не работает, потому что, когда он выполняется в веб-запросе, базовые классы модели кэшируют разные соединения с базой данных из пула соединений A / R. Таким образом, соединение, для которого я выполняю оператор «use», может не быть тем соединением, которое использует модель, и в этом случае она запрашивает неверную базу данных.
Я прочитал код Rails A / R (версия 3.0.3) и придумал этот код для выполнения в цикле вместо оператора «use»:
ActiveRecord::Base.clear_active_connections!
ActiveRecord::Base.establish_connection(each_customer_database_config)
Я полагаю, что пул соединений для каждого потока, поэтому кажется, что это приведет к засорению пула соединений и переустановит его только для одного потока, к которому подключен веб-запрос. Но если я не вижу общих подключений, я бы не хотел, чтобы этот код наносил ущерб другим активным веб-запросам в том же приложении.
Безопасно ли это делать в работающем веб-приложении? Есть ли другой способ сделать это?