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