提交 4f72feb8 编写于 作者: J Jonathan Viney 提交者: Michael Koziarski

Move the transaction counter to the connection object rather than maintaining...

Move the transaction counter to the connection object rather than maintaining it on the current Thread.
Signed-off-by: NMichael Koziarski <michael@koziarski.com>
[#533 state:resolved]
上级 24a8ae4e
......@@ -118,6 +118,19 @@ def raw_connection
@connection
end
def open_transactions
@open_transactions ||= 0
end
def increment_open_transactions
@open_transactions ||= 0
@open_transactions += 1
end
def decrement_open_transactions
@open_transactions -= 1
end
def log_info(sql, name, runtime)
if @logger && @logger.debug?
name = "#{name.nil? ? "SQL" : name} (#{sprintf("%f", runtime)})"
......
......@@ -515,7 +515,7 @@ def self.create_fixtures(fixtures_directory, table_names, class_names = {})
all_loaded_fixtures.update(fixtures_map)
connection.transaction(Thread.current['open_transactions'].to_i == 0) do
connection.transaction(connection.open_transactions.zero?) do
fixtures.reverse.each { |fixture| fixture.delete_existing_fixtures }
fixtures.each { |fixture| fixture.insert_fixtures }
......@@ -930,7 +930,7 @@ def setup_fixtures
load_fixtures
@@already_loaded_fixtures[self.class] = @loaded_fixtures
end
ActiveRecord::Base.send :increment_open_transactions
ActiveRecord::Base.connection.increment_open_transactions
ActiveRecord::Base.connection.begin_db_transaction
# Load fixtures for every test.
else
......@@ -951,9 +951,9 @@ def teardown_fixtures
end
# Rollback changes if a transaction is active.
if use_transactional_fixtures? && Thread.current['open_transactions'] != 0
if use_transactional_fixtures? && ActiveRecord::Base.connection.open_transactions != 0
ActiveRecord::Base.connection.rollback_db_transaction
Thread.current['open_transactions'] = 0
ActiveRecord::Base.connection.decrement_open_transactions
end
ActiveRecord::Base.verify_active_connections!
end
......
......@@ -73,25 +73,14 @@ def self.included(base)
# trigger a ROLLBACK when raised, but not be re-raised by the transaction block.
module ClassMethods
def transaction(&block)
increment_open_transactions
connection.increment_open_transactions
begin
connection.transaction(Thread.current['start_db_transaction'], &block)
connection.transaction(connection.open_transactions == 1, &block)
ensure
decrement_open_transactions
connection.decrement_open_transactions
end
end
private
def increment_open_transactions #:nodoc:
open = Thread.current['open_transactions'] ||= 0
Thread.current['start_db_transaction'] = open.zero?
Thread.current['open_transactions'] = open + 1
end
def decrement_open_transactions #:nodoc:
Thread.current['open_transactions'] -= 1
end
end
def transaction(&block)
......
......@@ -461,11 +461,11 @@ def blank_teardown; end
alias_method :teardown, :blank_teardown
def test_no_rollback_in_teardown_unless_transaction_active
assert_equal 0, Thread.current['open_transactions']
assert_equal 0, ActiveRecord::Base.connection.open_transactions
assert_raise(RuntimeError) { ar_setup_fixtures }
assert_equal 0, Thread.current['open_transactions']
assert_equal 0, ActiveRecord::Base.connection.open_transactions
assert_nothing_raised { ar_teardown_fixtures }
assert_equal 0, Thread.current['open_transactions']
assert_equal 0, ActiveRecord::Base.connection.open_transactions
end
private
......
......@@ -57,4 +57,29 @@ def test_course_connection_should_survive_dependency_reload
assert Course.connection
end
def test_transactions_across_databases
c1 = Course.find(1)
e1 = Entrant.find(1)
begin
Course.transaction do
Entrant.transaction do
c1.name = "Typo"
e1.name = "Typo"
c1.save
e1.save
raise "No I messed up."
end
end
rescue
# Yup caught it
end
assert_equal "Typo", c1.name
assert_equal "Typo", e1.name
assert_equal "Ruby Development", Course.find(1).name
assert_equal "Ruby Developer", Entrant.find(1).name
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册