Transactions
Get an idea of how database transactions work with an Active Record.
We'll cover the following
Database transactions
A database transaction groups a series of changes in such a way that either the database applies all of the changes or it applies none of the changes. The classic example of the need for transactions, which is used in Active Record’s own documentation is transferring money between two bank accounts. The basic logic is straightforward:
account1.deposit(100)
account2.withdraw(100)
However, we have to be careful. What happens if the deposit succeeds but, for some reason, the withdrawal fails. Perhaps the customer is overdrawn? We’ll have added $100
to the balance in account1
without a corresponding deduction from account2
. In effect, we’ll have created $100
out of thin air.
Luckily, transactions come to the rescue. A transaction is something like the Three Musketeers with their motto “All for one and one for all.” Within the scope of a transaction, either every SQL statement succeeds or they all have no effect. To put that another way, if any statement fails, the entire transaction has no effect on the database.
Transactions with active record
In Active Record, we use the transaction()
method to execute a block in the context of a particular database transaction. At the end of the block, the transaction is committed and updates the database unless an exception is raised within the block. In that case, the database rolls back all of the changes. Since transactions exist in the context of a database connection, we have to invoke them with an Active Record class as a receiver.
Thus, we could write this:
Account.transaction do
account1.deposit(100)
account2.withdraw(100)
end
Let’s experiment with transactions. We’ll start by creating a new database table.
Note: Make sure your database supports transactions, or this code won’t work for you.
Get hands-on with 1400+ tech skills courses.