mirror of
https://github.com/github/rails.git
synced 2026-02-18 18:05:07 -05:00
Reimplement Jeremy's PostgreSQL automatic transaction state introspection code.
- Fixed compatibility with the old 'postgres' driver which doesn't support transaction state introspection. - Added unit tests for it.
This commit is contained in:
@@ -53,6 +53,20 @@ module ActiveRecord
|
||||
def delete(sql, name = nil)
|
||||
delete_sql(sql, name)
|
||||
end
|
||||
|
||||
# Checks whether there is currently no transaction active. This is done
|
||||
# by querying the database driver, and does not use the transaction
|
||||
# house-keeping information recorded by #increment_open_transactions and
|
||||
# friends.
|
||||
#
|
||||
# Returns true if there is no transaction active, false if there is a
|
||||
# transaction active, and nil if this information is unknown.
|
||||
#
|
||||
# Not all adapters supports transaction state introspection. Currently,
|
||||
# only the PostgreSQL adapter supports this.
|
||||
def outside_transaction?
|
||||
nil
|
||||
end
|
||||
|
||||
# Runs the given block in a database transaction, and returns the result
|
||||
# of the block.
|
||||
@@ -119,7 +133,7 @@ module ActiveRecord
|
||||
yield
|
||||
end
|
||||
rescue Exception => database_transaction_rollback
|
||||
if transaction_open
|
||||
if transaction_open && !outside_transaction?
|
||||
transaction_open = false
|
||||
decrement_open_transactions
|
||||
if open_transactions == 0
|
||||
@@ -131,7 +145,9 @@ module ActiveRecord
|
||||
raise unless database_transaction_rollback.is_a? ActiveRecord::Rollback
|
||||
end
|
||||
ensure
|
||||
if transaction_open
|
||||
if outside_transaction?
|
||||
@open_transactions = 0
|
||||
elsif transaction_open
|
||||
decrement_open_transactions
|
||||
begin
|
||||
if open_transactions == 0
|
||||
|
||||
@@ -532,6 +532,16 @@ module ActiveRecord
|
||||
def rollback_db_transaction
|
||||
execute "ROLLBACK"
|
||||
end
|
||||
|
||||
if PGconn.public_method_defined?(:transaction_status)
|
||||
# ruby-pg defines Ruby constants for transaction status,
|
||||
# ruby-postgres does not.
|
||||
PQTRANS_IDLE = defined?(PGconn::PQTRANS_IDLE) ? PGconn::PQTRANS_IDLE : 0
|
||||
|
||||
def outside_transaction?
|
||||
@connection.transaction_status == PQTRANS_IDLE
|
||||
end
|
||||
end
|
||||
|
||||
def create_savepoint
|
||||
execute("SAVEPOINT #{current_savepoint_name}")
|
||||
|
||||
Reference in New Issue
Block a user