Skip to content

Commit

Permalink
Add allow_retry kwarg to execute
Browse files Browse the repository at this point in the history
This extends the existing class level auto_retry functionality to
optionally allow an allow_retry boolean kwarg to allow retry of specific
queries.

This PR preserves the requirement that `autocommit?` be enabled which is the
safer choice.

```
  def with_retry(allow_retry: false) # :nodoc:
    should_retry = (allow_retry || self.class.auto_retry?) && autocommit?
```

See issue rsim#2310
  • Loading branch information
andynu committed Mar 19, 2024
1 parent 7500049 commit 7e566d5
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ module DatabaseStatements
# see: abstract/database_statements.rb

# Executes a SQL statement
def execute(sql, name = nil, async: false)
def execute(sql, name = nil, async: false, allow_retry: false)
sql = transform_query(sql)

log(sql, name, async: async) { @raw_connection.exec(sql) }
log(sql, name, async: async) { @raw_connection.exec(sql, allow_retry: allow_retry) }
end

def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ def reset!
raise OracleEnhanced::ConnectionException, e.message
end

def exec(sql, *bindvars, &block)
@raw_connection.exec(sql, *bindvars, &block)
def exec(sql, *bindvars, allow_retry: false, &block)
with_retry(allow_retry: allow_retry) { @raw_connection.exec(sql, *bindvars, &block) }
end

def with_retry(&block)
@raw_connection.with_retry(&block)
def with_retry(allow_retry: false, &block)
@raw_connection.with_retry(allow_retry: allow_retry, &block)
end

def prepare(sql)
Expand Down Expand Up @@ -435,8 +435,8 @@ def reset! # :nodoc:
LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114, 3135 ] # :nodoc:

# Adds auto-recovery functionality.
def with_retry # :nodoc:
should_retry = self.class.auto_retry? && autocommit?
def with_retry(allow_retry: false) # :nodoc:
should_retry = (allow_retry || self.class.auto_retry?) && autocommit?

begin
yield
Expand All @@ -451,7 +451,7 @@ def with_retry # :nodoc:
end

def exec(sql, *bindvars, &block) # :nodoc:
with_retry { @raw_connection.exec(sql, *bindvars, &block) }
@raw_connection.exec(sql, *bindvars, &block)
end
end
# :startdoc:
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,11 @@ def kill_current_session
expect(@conn.exec("SELECT * FROM dual")).not_to be_nil
end

it "should reconnect and execute SQL statement if connection is lost and allow_retry is passed" do
kill_current_session
expect(@conn.exec("SELECT * FROM dual", allow_retry: true)).not_to be_nil
end

it "should not reconnect and execute SQL statement if connection is lost and auto retry is disabled" do
# @conn.auto_retry = false
ActiveRecord::Base.connection.auto_retry = false
Expand Down

0 comments on commit 7e566d5

Please sign in to comment.