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