Ensure disconnecting or reconnecting resets the transaction state

This commit is contained in:
Jon Leighton 2012-09-14 23:59:35 +01:00
parent 6195142790
commit 02f56554d6
7 changed files with 55 additions and 9 deletions

@ -69,7 +69,6 @@ class AbstractAdapter
def initialize(connection, logger = nil, pool = nil) #:nodoc:
super()
@active = nil
@connection = connection
@in_use = false
@instrumenter = ActiveSupport::Notifications.instrumenter
@ -187,19 +186,21 @@ def disable_referential_integrity
# checking whether the database is actually capable of responding, i.e. whether
# the connection isn't stale.
def active?
@active != false
end
# Disconnects from the database if already connected, and establishes a
# new connection with the database.
# new connection with the database. Implementors should call super if they
# override the default implementation.
def reconnect!
@active = true
clear_cache!
reset_transaction
end
# Disconnects from the database if already connected. Otherwise, this
# method does nothing.
def disconnect!
@active = false
clear_cache!
reset_transaction
end
# Reset the state of this connection, directing the DBMS to clear

@ -74,6 +74,7 @@ def active?
end
def reconnect!
super
disconnect!
connect
end
@ -82,6 +83,7 @@ def reconnect!
# Disconnects from the database if already connected.
# Otherwise, this method does nothing.
def disconnect!
super
unless @connection.nil?
@connection.close
@connection = nil

@ -189,14 +189,15 @@ def active?
end
def reconnect!
super
disconnect!
clear_cache!
connect
end
# Disconnects from the database if already connected. Otherwise, this
# method does nothing.
def disconnect!
super
@connection.close rescue nil
end

@ -431,7 +431,7 @@ def active?
# Close then reopen the connection.
def reconnect!
clear_cache!
super
@connection.reset
configure_connection
end
@ -444,7 +444,7 @@ def reset!
# Disconnects from the database if already connected. Otherwise, this
# method does nothing.
def disconnect!
clear_cache!
super
@connection.close rescue nil
end

@ -104,6 +104,8 @@ class BindSubstitution < Arel::Visitors::SQLite # :nodoc:
def initialize(connection, logger, config)
super(connection, logger)
@active = nil
@statements = StatementPool.new(@connection,
config.fetch(:statement_limit) { 1000 })
@config = config
@ -154,11 +156,15 @@ def supports_add_column?
true
end
def active?
@active != false
end
# Disconnects from the database if already connected. Otherwise, this
# method does nothing.
def disconnect!
super
clear_cache!
@active = false
@connection.close rescue nil
end

@ -36,6 +36,10 @@ def merge_column(table_name, name, sql_type = nil, options = {})
def columns(table_name)
@columns[table_name]
end
def active?
true
end
end
end
end

@ -160,4 +160,36 @@ def test_disable_referential_integrity
end
end
end
class AdapterTestWithoutTransaction < ActiveRecord::TestCase
self.use_transactional_fixtures = false
def setup
@klass = Class.new(ActiveRecord::Base)
@klass.establish_connection 'arunit'
@connection = @klass.connection
end
def teardown
@klass.remove_connection
end
test "transaction state is reset after a reconnect" do
skip "in-memory db doesn't allow reconnect" if in_memory_db?
@connection.begin_transaction
assert @connection.transaction_open?
@connection.reconnect!
assert !@connection.transaction_open?
end
test "transaction state is reset after a disconnect" do
skip "in-memory db doesn't allow disconnect" if in_memory_db?
@connection.begin_transaction
assert @connection.transaction_open?
@connection.disconnect!
assert !@connection.transaction_open?
end
end
end