Transactions refactoring

Add a transaction manager per connection, so it can controls the
connection responsibilities.

Delegate transaction methods to transaction_manager
上级 368525a5
......@@ -203,62 +203,30 @@ def transaction(options = {})
if options[:isolation]
raise ActiveRecord::TransactionIsolationError, "cannot set isolation when joining a transaction"
end
yield
else
within_new_transaction(options) { yield }
transaction_manager.within_new_transaction(options) { yield }
end
rescue ActiveRecord::Rollback
# rollbacks are silently swallowed
end
def within_new_transaction(options = {}) #:nodoc:
transaction = begin_transaction(options)
yield
rescue Exception => error
rollback_transaction if transaction
raise
ensure
begin
commit_transaction unless error
rescue Exception
rollback_transaction
raise
end
end
def open_transactions
@transaction.number
end
attr_reader :transaction_manager #:nodoc:
def current_transaction #:nodoc:
@transaction
end
delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction, :commit_transaction, :rollback_transaction, to: :transaction_manager
def transaction_open?
@transaction.open?
end
def begin_transaction(options = {}) #:nodoc:
@transaction = @transaction.begin(options)
end
def commit_transaction #:nodoc:
@transaction = @transaction.commit
end
def rollback_transaction #:nodoc:
@transaction = @transaction.rollback
current_transaction.open?
end
def reset_transaction #:nodoc:
@transaction = ClosedTransaction.new(self)
@transaction_manager = TransactionManager.new(self)
end
# Register a record with the current transaction so that its after_commit and after_rollback callbacks
# can be called.
def add_transaction_record(record)
@transaction.add_record(record)
current_transaction.add_record(record)
end
# Begins the transaction (and turns off auto-committing).
......
module ActiveRecord
module ConnectionAdapters
class TransactionManager #:nodoc:
def initialize(connection)
@stack = []
@connection = connection
end
def begin_transaction(options = {})
transaction =
if @stack.empty?
RealTransaction.new(@connection, current_transaction, options)
else
SavepointTransaction.new(@connection, current_transaction, options)
end
@stack.push(transaction)
transaction
end
def commit_transaction
@stack.pop.commit
end
def rollback_transaction
@stack.pop.rollback
end
def within_new_transaction(options = {})
transaction = begin_transaction options
yield
rescue Exception => error
transaction.rollback if transaction
raise
ensure
begin
transaction.commit unless error
rescue Exception
transaction.rollback
raise
ensure
@stack.pop if transaction
end
end
def open_transactions
@stack.size
end
def current_transaction
@stack.last || closed_transaction
end
private
def closed_transaction
@closed_transaction ||= ClosedTransaction.new(@connection)
end
end
class Transaction #:nodoc:
attr_reader :connection
......
......@@ -45,6 +45,7 @@ module ConnectionAdapters # :nodoc:
end
autoload_at 'active_record/connection_adapters/abstract/transaction' do
autoload :TransactionManager
autoload :ClosedTransaction
autoload :RealTransaction
autoload :SavepointTransaction
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册