aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/abstract/transaction.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/transaction.rb50
1 files changed, 36 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
index 4a7f2aaca8..fd666c8c39 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb
@@ -22,6 +22,10 @@ module ActiveRecord
@state == :rolledback
end
+ def completed?
+ committed? || rolledback?
+ end
+
def set_state(state)
if !VALID_STATES.include?(state)
raise ArgumentError, "Invalid transaction state: #{state}"
@@ -63,13 +67,19 @@ module ActiveRecord
end
def rollback_records
- records.uniq.each do |record|
+ ite = records.uniq
+ while record = ite.shift
begin
record.rolledback! full_rollback?
rescue => e
+ raise if ActiveRecord::Base.raise_in_transactional_callbacks
record.logger.error(e) if record.respond_to?(:logger) && record.logger
end
end
+ ensure
+ ite.each do |i|
+ i.rolledback!(full_rollback?, false)
+ end
end
def commit
@@ -77,13 +87,19 @@ module ActiveRecord
end
def commit_records
- records.uniq.each do |record|
+ ite = records.uniq
+ while record = ite.shift
begin
record.committed!
rescue => e
+ raise if ActiveRecord::Base.raise_in_transactional_callbacks
record.logger.error(e) if record.respond_to?(:logger) && record.logger
end
end
+ ensure
+ ite.each do |i|
+ i.committed!(false)
+ end
end
def full_rollback?; true; end
@@ -103,14 +119,16 @@ module ActiveRecord
end
def rollback
- super
connection.rollback_to_savepoint(savepoint_name)
+ super
rollback_records
end
def commit
- super
connection.release_savepoint(savepoint_name)
+ super
+ parent = connection.transaction_manager.current_transaction
+ records.each { |r| parent.add_record(r) }
end
def full_rollback?; false; end
@@ -128,14 +146,14 @@ module ActiveRecord
end
def rollback
- super
connection.rollback_db_transaction
+ super
rollback_records
end
def commit
- super
connection.commit_db_transaction
+ super
commit_records
end
end
@@ -169,16 +187,20 @@ module ActiveRecord
transaction = begin_transaction options
yield
rescue Exception => error
- transaction.rollback if transaction
+ rollback_transaction if transaction
raise
ensure
- begin
- transaction.commit unless error
- rescue Exception
- transaction.rollback
- raise
- ensure
- @stack.pop if transaction
+ unless error
+ if Thread.current.status == 'aborting'
+ rollback_transaction
+ else
+ begin
+ commit_transaction
+ rescue Exception
+ transaction.rollback unless transaction.state.completed?
+ raise
+ end
+ end
end
end