Rails 1.2.3でOracleでConnectionNotEstablishedが発生する場合は?
# rak ConnectionNotEstablished /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/ 19| class ConnectionNotEstablished < ActiveRecordError #:nodoc: 251| # * +ConnectionNotEstablished+ -- no connection has been established. Use <tt>establish_connection</tt> before querying. /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/connection_specification.rb 235| conn or raise ConnectionNotEstablished 264| raise ConnectionNotEstablished /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/firebird_adapter.rb 97| raise ConnectionNotEstablished, "No Firebird connections established."
ConnectionNotEstablishedが発生する箇所は二カ所
- ActiveRecord::Base::ConnectionSpecification.retrieve_connection
- ActiveRecord::Base::ConnectionSpecification.connection=
connection=は初回にDB接続するとき
retrieve_connectionは初回接続以後DBコネクションを取得するとき
それぞれ呼ばれる
connection=
connection=でConnectionNotEstablishedが発生するのは
接続設定がnilだったとき
このコードは通らないと思う・・
呼び先(retrieve_connection)でnilだったらこのメソッド呼ばれないし
retrieve_connection
DBコネクションオブジェクト(ConnectionAdapters::OracleAdapter)がnilになってたらConnectionNotEstablishedが発生する
nilになるのはremove_connectionされてた場合かなあ
def self.remove_connection(klass=self) spec = @@defined_connections[klass.name] konn = active_connections[klass.name] @@defined_connections.delete_if { |key, value| value == spec } active_connections.delete_if { |key, value| value == konn } konn.disconnect! if konn spec.config if spec end
テスト
/opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.3/test/unconnected_test.rb
にConnectionNotEstablishedのテストがある
setupでremove_connectionしてる
ConnectionNotEstablishedを起こす
無理栗に起こそうとしたらこんなんだけど(RailsのバージョンもDBも違うけどremove_connectionの動きは同じ)こんなんアプリのコードで書かないやん
# ruby script/console Loading development environment (Rails 2.2.2) >> ActiveRecord::Base.remove_connection => {:timeout=>5000, :adapter=>"sqlite3", :pool=>5, :database=>"/Users/sogo/code/rails/jpmobile-demo/db/development.sqlite3"} >> Post.find :first ActiveRecord::ConnectionNotEstablished: ActiveRecord::ConnectionNotEstablished from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract/connection_pool.rb:326:in `retrieve_connection' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:121:in `retrieve_connection' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:113:in `connection' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2934:in `quoted_table_name' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1626:in `construct_finder_sql' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1490:in `find_every' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:1452:in `find_initial' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:587:in `find' from (irb):4 >>
ちなみにalter system kill sessionしてかららDB接続するとRuntimeErrorが発生するはず
OCI8AutoRecoverの@@auto_retry?はfalseでshould_retryもfalseなので
# ORA-00028: your session has been killed # ORA-01012: not logged on # ORA-03113: end-of-file on communication channel # ORA-03114: not connected to ORACLE LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114 ] # Adds auto-recovery functionality. # # See: http://www.jiubao.org/ruby-oci8/api.en.html#label-11 def exec(sql, *bindvars, &block) should_retry = self.class.auto_retry? && autocommit? begin @connection.exec(sql, *bindvars, &block) rescue OCIException => e raise unless LOST_CONNECTION_ERROR_CODES.include?(e.code) @active = false raise unless should_retry should_retry = false reset! rescue nil retry end end end