aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHongli Lai (Phusion) <hongli@phusion.nl>2008-09-16 13:15:00 +0200
committerHongli Lai (Phusion) <hongli@phusion.nl>2008-09-16 13:15:00 +0200
commitfeacc377b7a1fee0a78e17784cd405b07809335b (patch)
tree379d74ed088c6806a4402e8339800dbc5eec2cbc
parent253259f391dbec534015972566ec74f17582bf2f (diff)
downloadrails-feacc377b7a1fee0a78e17784cd405b07809335b.tar.gz
rails-feacc377b7a1fee0a78e17784cd405b07809335b.tar.bz2
rails-feacc377b7a1fee0a78e17784cd405b07809335b.zip
Warn about statement errors causing a transaction to become unusable on PostgreSQL.
-rw-r--r--activerecord/lib/active_record/transactions.rb28
1 files changed, 28 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index b9def51363..86a5142a97 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -92,6 +92,34 @@ module ActiveRecord
#
# One exception is the ActiveRecord::Rollback exception, which will trigger
# a ROLLBACK when raised, but not be re-raised by the transaction block.
+ #
+ # *Warning*: one should not catch ActiveRecord::StatementInvalid exceptions
+ # inside a transaction block. StatementInvalid exceptions indicate that an
+ # error occurred at the database level, for example when a unique constraint
+ # is violated. On some database systems, such as PostgreSQL, database errors
+ # inside a transaction causes the entire transaction to become unusable
+ # until it's restarted from the beginning. Here is an example which
+ # demonstrates the problem:
+ #
+ # # Suppose that we have a Number class with a unique column called 'i'.
+ # Number.transaction do
+ # Number.create(:i => 0)
+ # begin
+ # # This will raise a unique constraint error...
+ # Number.create(:i => 0)
+ # rescue ActiveRecord::StatementInvalid
+ # # ...which we ignore.
+ # end
+ #
+ # # On PostgreSQL, the transaction is now unusable. The following
+ # # statement will cause a PostgreSQL error, even though the unique
+ # # constraint is no longer violated:
+ # Number.create(:i => 1)
+ # # => "PGError: ERROR: current transaction is aborted, commands
+ # # ignored until end of transaction block"
+ # end
+ #
+ # One should restart the entire transaction if a StatementError occurred.
module ClassMethods
# See ActiveRecord::Transactions::ClassMethods for detailed documentation.
def transaction(&block)