各サブドメインに個別のデータベースがあるRailsアプリケーションを開発しています。そして、私はこのようなことをしています。
#app/controller/application_controller.rb
class ApplicationController < ActionController::Base
before_filter :select_database
private
def select_database
MyModel.use_database(request.subdomains.first)
end
end
#app/model/my_model.rb
class MyModel < ActiveRecord::Base
def self.use_database path
establish_connection :adapter => 'sqlite3', :database =>
File.join(RAILS_ROOT, "db", "sqlite3", path)
end
end
これで、production
モードでは、要求がこの順序で来て実行されます。
- リクエスト「A」はサブドメインa.example.net
MyModel
に送信され、データベース「a」との接続を確立します。 - ここで、別のリクエスト「B」がサブドメインb.example.net
MyModel
に送信され、データベース「b」との接続を確立します。 - ここで、リクエスト「A」がどのデータベースにアクセスしようとした場合、
MyModel.find_*()
どのデータベースにアクセスしますか?「a」または「b」?
これが「スレッドセーフ」または「競合状態」と呼ばれるものだと思います。そうであれば、サブドメインごとに1つのデータベースを使用してアプリケーションを実装するときに、どうすればそれを回避できますか?
上記の質問では、2つのリクエストを同時に実行することは、運用サーバーの通常の動作であると想定しています。または、より良いアプローチがありますか。本番サーバーの経験はあまりないので、アドバイスをお願いします。