First off, I am having issues updating my code for Edge Rails with an XP client, so please forgive me that I cannot submit a proper patch.
Given a rails project with muliple Database connections where you wanted to do a transaction across both databases, the standard practice was to create a transaction across both databases as such:
RecordOnDatabaseOne.transaction do
RecordOnDatabaseTwo.transaction do
data_db1.save
data_db2.save
end
end
However, there has been a change to the way transactions were handled that makes this no longer work properly. If you execute the following:
RecordOnDatabaseOne.transaction do
RecordOnDatabaseTwo.transaction do
data_db1.save
data_db2.save
raise "nevermind"
end
end
Database 1 will properly rollback but NOT database 2. The problem has to do with the transaction counter that is implemented in the rails code:
# File active_record/transactions.rb, line 98
def increment_open_transactions #:nodoc:
open = Thread.current['open_transactions'] ||= 0
Thread.current['start_db_transaction'] = open.zero?
Thread.current['open_transactions'] = open + 1
end
# File active_record/transactions.rb, line 104
def decrement_open_transactions #:nodoc:
Thread.current['open_transactions'] -= 1
end
As you can see the counter is kept on the Thread making the counter one global object for the whole Rails App. The thread counter should be stored on the connection object for the ActiveRecord object.
Because of some issues with my subversion client not being able to update my current edge rails I am not able to submit a proper patch, but I have attached my monkey patch that I am currently using in my application.