| 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 617
617: def initialize(config, factory = OracleConnectionFactory.new)
618: @active = true
619: @username, @password, @database, = config[:username], config[:password], config[:database]
620: @async = config[:allow_concurrency]
621: @prefetch_rows = config[:prefetch_rows] || 100
622: @cursor_sharing = config[:cursor_sharing] || 'similar'
623: @factory = factory
624: @connection = @factory.new_connection @username, @password, @database, @async, @prefetch_rows, @cursor_sharing
625: super @connection
626: 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 661
661: def exec(sql, *bindvars, &block)
662: should_retry = self.class.auto_retry? && autocommit?
663:
664: begin
665: @connection.exec(sql, *bindvars, &block)
666: rescue OCIException => e
667: raise unless LOST_CONNECTION_ERROR_CODES.include?(e.code)
668: @active = false
669: raise unless should_retry
670: should_retry = false
671: reset! rescue nil
672: retry
673: end
674: 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 631
631: def ping
632: @connection.exec("select 1 from dual") { |r| nil }
633: @active = true
634: rescue
635: @active = false
636: raise
637: end
Resets connection, by logging off and creating a new connection.
# File vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb, line 640
640: def reset!
641: logoff rescue nil
642: begin
643: @connection = @factory.new_connection @username, @password, @database, @async, @prefetch_rows, @cursor_sharing
644: __setobj__ @connection
645: @active = true
646: rescue
647: @active = false
648: raise
649: end
650: end