Merge pull request #49802 from composerinteralia/postgres-unrecoverable-connection-error
Recover from failed connections in PostgreSQL
This commit is contained in:
commit
c0e67e6547
@ -903,10 +903,10 @@ def exec_cache(sql, name, binds, async:, allow_retry:, materialize_transactions:
|
||||
|
||||
update_typemap_for_default_timezone
|
||||
|
||||
stmt_key = prepare_statement(sql, binds)
|
||||
type_casted_binds = type_casted_binds(binds)
|
||||
|
||||
with_raw_connection do |conn|
|
||||
stmt_key = prepare_statement(sql, binds, conn)
|
||||
type_casted_binds = type_casted_binds(binds)
|
||||
|
||||
log(sql, name, binds, type_casted_binds, stmt_key, async: async) do
|
||||
conn.exec_prepared(stmt_key, type_casted_binds)
|
||||
end
|
||||
@ -956,22 +956,20 @@ def sql_key(sql)
|
||||
|
||||
# Prepare the statement if it hasn't been prepared, return
|
||||
# the statement key.
|
||||
def prepare_statement(sql, binds)
|
||||
with_raw_connection(allow_retry: true, materialize_transactions: false) do |conn|
|
||||
sql_key = sql_key(sql)
|
||||
unless @statements.key? sql_key
|
||||
nextkey = @statements.next_key
|
||||
begin
|
||||
conn.prepare nextkey, sql
|
||||
rescue => e
|
||||
raise translate_exception_class(e, sql, binds)
|
||||
end
|
||||
# Clear the queue
|
||||
conn.get_last_result
|
||||
@statements[sql_key] = nextkey
|
||||
def prepare_statement(sql, binds, conn)
|
||||
sql_key = sql_key(sql)
|
||||
unless @statements.key? sql_key
|
||||
nextkey = @statements.next_key
|
||||
begin
|
||||
conn.prepare nextkey, sql
|
||||
rescue => e
|
||||
raise translate_exception_class(e, sql, binds)
|
||||
end
|
||||
@statements[sql_key]
|
||||
# Clear the queue
|
||||
conn.get_last_result
|
||||
@statements[sql_key] = nextkey
|
||||
end
|
||||
@statements[sql_key]
|
||||
end
|
||||
|
||||
# Connects to a PostgreSQL server and sets up the adapter depending on the
|
||||
|
@ -612,6 +612,20 @@ def teardown
|
||||
assert_predicate @connection, :active?
|
||||
end
|
||||
|
||||
test "querying after a failed query restores and succeeds" do
|
||||
Post.first # Connection verified (and prepared statement pool populated if enabled)
|
||||
|
||||
remote_disconnect @connection
|
||||
|
||||
assert_raises(ActiveRecord::ConnectionFailed) do
|
||||
Post.first # Connection no longer verified after failed query
|
||||
end
|
||||
|
||||
assert Post.first # Verifying the connection causes a reconnect and the query succeeds
|
||||
|
||||
assert_predicate @connection, :active?
|
||||
end
|
||||
|
||||
test "transaction restores after remote disconnection" do
|
||||
remote_disconnect @connection
|
||||
Post.transaction do
|
||||
|
Loading…
Reference in New Issue
Block a user