Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #10212 (closed defect: duplicate)

Opened 8 months ago

Last modified 4 days ago

Nested transactions across multiple Databases no longer work properly

Reported by: delwaterman Assigned to: bitsweat
Priority: normal Milestone: 2.x
Component: ActiveRecord Version: edge
Severity: major Keywords: transactions
Cc:

Description

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.

Attachments

transaction_fix.rb (1.6 kB) - added by delwaterman on 11/19/07 19:20:05.
Monkey Patch of Transaction Issue.
multi_db_transaction_patch.txt (2.0 kB) - added by delwaterman on 11/19/07 22:32:41.
Real Patch for Edge Rails (without tests)
mutil_db_transaction_with_tests.txt (3.0 kB) - added by delwaterman on 11/20/07 15:22:11.
Full patch with Tests

Change History

11/19/07 19:20:05 changed by delwaterman

  • attachment transaction_fix.rb added.

Monkey Patch of Transaction Issue.

11/19/07 22:32:41 changed by delwaterman

  • attachment multi_db_transaction_patch.txt added.

Real Patch for Edge Rails (without tests)

11/19/07 22:52:16 changed by delwaterman

OK, you guys seemed to resolved the issue with Subversion, so I have submitted my real patch. I am working on the test right now.

11/19/07 23:48:39 changed by delwaterman

Finished full patch with Tests.

11/19/07 23:50:57 changed by bitsweat

  • owner changed from core to bitsweat.

Thanks! Good catch and fix. I'll take a look soon.

11/20/07 15:22:11 changed by delwaterman

  • attachment mutil_db_transaction_with_tests.txt added.

Full patch with Tests

12/06/07 19:51:16 changed by delwaterman

Will this patch be applied to Rails 2.0? We would like to upgrade but we are still waiting for this to be addressed.

12/06/07 20:02:15 changed by bitsweat

  • keywords set to transactions.

2.0 is in release candidates, so it'll be included shortly thereafter.

Looks like the old unused increment_ and decrement_transactions methods can be removed btw.

12/17/07 16:57:22 changed by delwaterman

Just checking in, what is the status of getting this patch into a release. We cannot upgrade to Rails 2.0 until this patch gets applied.

Thanks for your help.

07/02/08 13:06:44 changed by jonathan_viney

  • status changed from new to closed.
  • resolution set to duplicate.