Rails nested transactions Rails nested transactions database database

Rails nested transactions


ActiveRecord::Rollback does not propagate outside of the containing transaction block and so the parent transaction does not receive the exception nested inside the child.

To ensure a rollback is received by the parent transaction you must add the requires_new: true option to the child transaction.

Check out this article and docs for more details.

So applying it to your case, you should have the user_service.rb as follows:

class UserService  def self.reduce_balance!(user, delta, attachmentable)    ActiveRecord::Base.transaction(requires_new: true) do      # code omitted    end  endend


Your issues stems from the way you use transactions.

Whenever you nest them you have to use requires_new: true

ActiveRecord::Base.transaction do   ActiveRecord::Base.transaction(requires_new: true) do   endend

Its explained well in the doc.

Btw, it doesnt hurt to always use requires_new: true.


Sidenote, you seem to use service objects and chain them, maybe this would interest you.