| Class | OCI8AutoRecover |
| In: |
vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb
|
| Parent: | DelegateClass(OCI8) |
The OCI8AutoRecover class enhances the OCI8 driver with auto-recover and reset functionality. If a call to exec fails, and autocommit is turned on (ie., we’re not in the middle of a longer transaction), it will automatically reconnect and try again. If autocommit is turned off, this would be dangerous (as the earlier part of the implied transaction may have failed silently if the connection died) — so instead the connection is marked as dead, to be reconnected on it’s next use.
| LOST_CONNECTION_ERROR_CODES | = | [ 28, 1012, 3113, 3114 ] | 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 |
| active | -> | active? |
| auto_retry | -> | auto_retry? |
| active | [RW] |
# File vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb, line 571
571: def initialize(config, factory = OracleConnectionFactory.new)
572: @active = true
573: @username, @password, @database, = config[:username], config[:password], config[:database]
574: @async = config[:allow_concurrency]
575: @factory = factory
576: @connection = @factory.new_connection @username, @password, @database, @async
577: super @connection
578: end
Adds auto-recovery functionality.
See: www.jiubao.org/ruby-oci8/api.en.html#label-11
# File vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb, line 613
613: def exec(sql, *bindvars, &block)
614: should_retry = self.class.auto_retry? && autocommit?
615:
616: begin
617: @connection.exec(sql, *bindvars, &block)
618: rescue OCIException => e
619: raise unless LOST_CONNECTION_ERROR_CODES.include?(e.code)
620: @active = false
621: raise unless should_retry
622: should_retry = false
623: reset! rescue nil
624: retry
625: end
626: end
Checks connection, returns true if active. Note that ping actively checks the connection, while active? simply returns the last known state.
# File vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb, line 583
583: def ping
584: @connection.exec("select 1 from dual") { |r| nil }
585: @active = true
586: rescue
587: @active = false
588: raise
589: end
Resets connection, by logging off and creating a new connection.
# File vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb, line 592
592: def reset!
593: logoff rescue nil
594: begin
595: @connection = @factory.new_connection @username, @password, @database, @async
596: __setobj__ @connection
597: @active = true
598: rescue
599: @active = false
600: raise
601: end
602: end