diff options
author | Hongli Lai (Phusion) <hongli@phusion.nl> | 2008-10-09 17:57:49 +0200 |
---|---|---|
committer | Hongli Lai (Phusion) <hongli@phusion.nl> | 2008-11-03 20:56:28 +0100 |
commit | fb2325e35855d62abd2c76ce03feaa3ca7992e4f (patch) | |
tree | 4864fc83385f6329441b950a83f807a97f59b1e3 /activerecord/lib | |
parent | e916aa7ea1613be966959c05ad41d13fee55a683 (diff) | |
download | rails-fb2325e35855d62abd2c76ce03feaa3ca7992e4f.tar.gz rails-fb2325e35855d62abd2c76ce03feaa3ca7992e4f.tar.bz2 rails-fb2325e35855d62abd2c76ce03feaa3ca7992e4f.zip |
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.
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb | 20 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 10 |
2 files changed, 28 insertions, 2 deletions
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 bd434f2efc..a9a63e5a9f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -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 diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 828f321767..c4ef2be82e 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -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}") |