A few things to consider when using Rails transactions


A sequence of database operations that satisfies the ACID properties and, thus, can be perceived as a single logical operation on the data is called a transaction. A good example for a transaction is transfer between two accounts where a deposit is complete only if the withdrawal is success and vice versa.

Here are few points which you should look at, if you’re using, or planning to use transactions in your rails application.

Need for transaction

Evaluate your use case thoroughly and make sure that transaction is the only possible solution. Because in most of the cases it will be possible to achieve transactional behaviour by using autosave or nested attributes on relations if the models are related.

It is always better to avoid transactions whenever possible, because transactions add overhead on database server and also have impact on performance when transaction boundary(no. of rows in a transaction) is too small or too large.

Am I using it correctly

If you’re using transactions already, it is very essential to make sure that you’re using it the right way. These are the few things which you shouldn’t be doing

  • Using operations which doesn’t support rollback, Ex: deleting a file
  • Using transactions when operations on only one record is involved. There in no need of transaction in such use cases since, methods like save, create, update are by default wrapped inside a transaction

Am I using it at the right place

In rails its recommended to have all business logic in models and keep controller skinny. So its better to have transactions in models than in controller. Keeping transactions in model also improves reusability and testability, and moreover guarantees consistency of its behaviour.

Handling the transaction block

Rails transactions are rolled back if any exception is thrown from the transaction block. Important thing to consider here is that, except for ActiveRecrod::RollBack, any other exceptions raised from inside will not be rescued. So its your responsibility to handle those exceptions.


  ActiveRecord::Base.transaction do                         
    if some_condition                                      
      # This will not go to rescue block     
      raise ActiveRecord::Rollback                         
      raise "some error"                                   
rescue => e                                                
  Rails.logger.info "Something went wrong, error: #{e}"