A few things to consider when using Rails transactions

download-2

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.

Ex:

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s