aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/transactions.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/transactions.rb')
-rw-r--r--activerecord/lib/active_record/transactions.rb35
1 files changed, 29 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 09318879d5..e008b32170 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -1,6 +1,32 @@
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
@@ -307,11 +333,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
@@ -327,20 +353,17 @@ 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[:level] = (@_start_transaction_state[:level] || 0) - 1
- @_start_transaction_state.clear if @_start_transaction_state[:level] < 1
+ @_start_transaction_state.clear if @txn.committed?
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?
- @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
- if @_start_transaction_state[:level] < 1 || force
+ if @txn.aborted? || force
restore_state = @_start_transaction_state
was_frozen = @attributes.frozen?
@attributes = @attributes.dup if was_frozen