Rails Save a record within transaction even if transaction rolls back?
ruby-on-rails-3, transactions
Solution
I'm not 100% sure I understand why you want to do this but could you just save the credit card stuff outside of your transaction?
result = nil
Payment.transaction do
payment.save
other.save
result = credit_card.purchase # this does the gateway transaction, no database stuff
if result.failure
raise ActiveRecord::Rollback
end
end
result.save
(you need to set result to nil before the transaction because of how block variable scoping works)
Another possible strategy is to use the fact that transactions are done a per connection basis. Two threads will use different connections, so you could do:
Payment.transaction do
payment.save
other.save
result = Thread.new do
ActiveRecord::Base.connection_pool.with_connection do
credit_card.purchase.tap do |result|
result.save
end
end
end.join.value
if result.failure
raise ActiveRecord::Rollback
end
end
or maybe just:
Payment.transaction do
payment.save
other.save
result = credit_card.purchase
Thread.new do
ActiveRecord::Base.connection_pool.with_connection do
result.save
end
end.join
if result.failure
raise ActiveRecord::Rollback
end
end
Here the purchase happens on another thread, i.e. with its own database connection. Anything that happens in that thread won't be rolled back
Problem
I have a series of records to save as part of a transaction. In addition to normal AR records, I am doing a credit card gateway transaction. If it or the AR transactions fail, I want everything rolled back ... except for the data of the failed transaction (reason, date, etc.) that I get back from the credit card gateway. Something like ``` def pay Payment.transaction do payment.save other.save result = credit_card.purchase # this does the gateway transaction, no database stuff if result.failure raise ActiveRecord::Rollback result.save # this is the part I want to always save end another.save end end ``` Is there a way to exclude a specific part within a transaction from rollback on failure? Rails 3.2.5, MySQL 5.1