aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/transactions.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2004-12-22 00:48:24 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2004-12-22 00:48:24 +0000
commit44819b47179936492c093811ed0f625ce6e029a3 (patch)
treef6653b9e9a9c8fd41dab1cc40f78e4e4d565b65c /activerecord/lib/active_record/transactions.rb
parent58f2bd0cfc1713ee3ed519d6b75bbfa386c131c3 (diff)
downloadrails-44819b47179936492c093811ed0f625ce6e029a3.tar.gz
rails-44819b47179936492c093811ed0f625ce6e029a3.tar.bz2
rails-44819b47179936492c093811ed0f625ce6e029a3.zip
Fixed that nested transactions now work by letting the outer most transaction have the responsibilty of starting and rolling back the transaction. If any of the inner transactions swallow the exception raised, though, the transaction will not be rolled back. So always let the transaction bubble up even when you've dealt with local issues. Closes #231 and #340.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@242 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/transactions.rb')
-rw-r--r--activerecord/lib/active_record/transactions.rb24
1 files changed, 11 insertions, 13 deletions
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index d440e74346..16c56c58f0 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -77,13 +77,17 @@ module ActiveRecord
# Tribute: Object-level transactions are implemented by Transaction::Simple by Austin Ziegler.
module ClassMethods
def transaction(*objects, &block)
- TRANSACTION_MUTEX.lock
+ TRANSACTION_MUTEX.synchronize do
+ Thread.current['open_transactions'] ||= 0
+ Thread.current['start_db_transaction'] = (Thread.current['open_transactions'] == 0)
+ Thread.current['open_transactions'] += 1
+ end
begin
objects.each { |o| o.extend(Transaction::Simple) }
objects.each { |o| o.start_transaction }
- result = connection.transaction(&block)
+ result = connection.transaction(Thread.current['start_db_transaction'], &block)
objects.each { |o| o.commit_transaction }
return result
@@ -91,7 +95,9 @@ module ActiveRecord
objects.each { |o| o.abort_transaction }
raise
ensure
- TRANSACTION_MUTEX.unlock
+ TRANSACTION_MUTEX.synchronize do
+ Thread.current['open_transactions'] -= 1
+ end
end
end
end
@@ -101,19 +107,11 @@ module ActiveRecord
end
def destroy_with_transactions #:nodoc:
- if TRANSACTION_MUTEX.locked?
- destroy_without_transactions
- else
- transaction { destroy_without_transactions }
- end
+ transaction { destroy_without_transactions }
end
def save_with_transactions(perform_validation = true) #:nodoc:
- if TRANSACTION_MUTEX.locked?
- save_without_transactions(perform_validation)
- else
- transaction { save_without_transactions(perform_validation) }
- end
+ transaction { save_without_transactions(perform_validation) }
end
end
end