diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index 11e4d34de2..4e1f0e1d62 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -193,8 +193,7 @@ module ActiveRecord rescue Exception => database_transaction_rollback if transaction_open && !outside_transaction? transaction_open = false - txn = decrement_open_transactions - txn.aborted! + decrement_open_transactions if open_transactions == 0 rollback_db_transaction rollback_transaction_records(true) @@ -209,10 +208,9 @@ module ActiveRecord @transaction_joinable = last_transaction_joinable if outside_transaction? - @current_transaction = nil + @open_transactions = 0 elsif transaction_open - txn = decrement_open_transactions - txn.committed! + decrement_open_transactions begin if open_transactions == 0 commit_db_transaction diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 27700e4fd2..b3f9187429 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -69,7 +69,6 @@ module ActiveRecord @last_use = false @logger = logger @open_transactions = 0 - @current_transaction = nil @pool = pool @query_cache = Hash.new { |h,sql| h[sql] = {} } @query_cache_enabled = false @@ -237,30 +236,14 @@ module ActiveRecord @connection end - def open_transactions - count = 0 - txn = current_transaction - - while txn - count += 1 - txn = txn.next - end - - count - end - - attr_reader :current_transaction + attr_reader :open_transactions def increment_open_transactions - @current_transaction = Transaction.new(current_transaction) + @open_transactions += 1 end def decrement_open_transactions - return unless current_transaction - - txn = current_transaction - @current_transaction = txn.next - txn + @open_transactions -= 1 end def transaction_joinable=(joinable) diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index cf64985ddb..43ffca0227 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -387,7 +387,6 @@ module ActiveRecord @marked_for_destruction = false @new_record = true @mass_assignment_options = nil - @txn = nil @_start_transaction_state = {} end end diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index e008b32170..09318879d5 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -1,32 +1,6 @@ require 'thread' module ActiveRecord - class Transaction - attr_reader :next - - def initialize(txn = nil) - @next = txn - @committed = false - @aborted = false - end - - def committed! - @committed = true - end - - def aborted! - @aborted = true - end - - def committed? - @committed - end - - def aborted? - @aborted - end - end - # See ActiveRecord::Transactions::ClassMethods for documentation. module Transactions extend ActiveSupport::Concern @@ -333,11 +307,11 @@ module ActiveRecord def with_transaction_returning_status status = nil self.class.transaction do - @txn = self.class.connection.current_transaction add_to_transaction begin status = yield rescue ActiveRecord::Rollback + @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 status = nil end @@ -353,17 +327,20 @@ module ActiveRecord @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key) @_start_transaction_state[:new_record] = @new_record @_start_transaction_state[:destroyed] = @destroyed + @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1 end # Clear the new record state and id of a record. def clear_transaction_record_state #:nodoc: - @_start_transaction_state.clear if @txn.committed? + @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 + @_start_transaction_state.clear if @_start_transaction_state[:level] < 1 end # Restore the new record state and id of a record that was previously saved by a call to save_record_state. def restore_transaction_record_state(force = false) #:nodoc: unless @_start_transaction_state.empty? - if @txn.aborted? || force + @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1 + if @_start_transaction_state[:level] < 1 || force restore_state = @_start_transaction_state was_frozen = @attributes.frozen? @attributes = @attributes.dup if was_frozen