As we all know in SQL transaction are used to maintain the integrity of the data, so that if there are multiple queries written, which has a condition that either all of them are executed or none. So for achieving those rails has written the wrappers for these sql transactions. The best example for transaction that comes in my mind always is the banking, if a money is deducted from one account, then it must be added to other account, otherwise none of them should get executed. i.e
ActiveRecord::Base.transaction do
## If A transfers some amount to B
# code to deduct money from A's account
# code to deposit money to B's account
end
In rails transaction is available for both class and objects, so you can use it on either class or its object. i.e.
SomeClass.transaction do
# Your code
end
some_object.transaction do
# Your code
end
Transactions are only needed if you requires check for updating multiple records, for updating single record, transaction is not required, also it is not object or class specific, so even if you are updating objects of different models, you can keep them in any of the transaction block of another class, it the objects are needed to be updated as single unit. So the below example will always work perfectly fine.
ClassA.transaction do
objectOfClassA.update
objectOfClassB.update
end
Rails supports nested transactions, in nested transactions, the child transaction block is considered as the part of the parent transaction, but they are needed to used very carefully, as we can see the following example:
User.transaction do
User.create(username: 'A')
User.transaction do
User.create(username: 'B')
raise ActiveRecord::Rollback
end
end
In this case both the users will get created as the parent block does not see the ActiveRecord::Rollback, to make a check for this you need to specify requires_new: true in the child transaction, in that case the parent transaction will know that something has gone wrong.
User.transaction do
User.create(username: 'A')
User.transaction(requires_new: true) do
User.create(username: 'B')
raise ActiveRecord::Rollback
end
end
Hope you liked reading it.
0 Comment(s)