Unit of Work design pattern does two important things: first it maintains in-memory updates and second it sends these in-memory updates as one transaction to the database.
So to achieve the above goals it goes through two steps:
- It maintains lists of business objects in-memory which have been changed (inserted, updated, or deleted) during a transaction.
- Once the transaction is completed, all these updates are sent as one big unit of work to be persisted physically in a database in one go.
A simple definition of Work means performing some task. From a software application perspective Work is nothing but inserting, updating, and deleting data. For instance let’s say you have an application which maintains customer data into a database.
So when you add, update, or delete a customer record on the database it’s one unit. In simple words the equation is.
1 customer CRUD = 1 unit of work
Where CRUD stands for create, read, update, and delete operation on a single customer record.
The equation which we discussed in the previous section changes a lot when it comes to real world scenarios. Now consider the below scenario where every customer can have multiple addresses. Then many rows will become 1 unit of work.
For example you can see in the below figure customer “Shiv” has two addresses, so for the below scenario the equation is:
3 Customer CRUD = 1 Logical unit of work
So in simple words, transactions for all of the three records should succeed or all of them should fail. It should be ATOMIC. In other words it’s very much possible that many CRUD operations will be equal to 1 unit of work.
Many developers can conclude that the above requirement can be met by initiating all the CRUD operations in one transaction. Definitely under the cover it uses database transactions (i.e.,
TransactionScope object). But unit of work is much more than simple database transactions, it sends only changes and not all rows to the database.
Let me explain to you the same in more detail.
Let’s say your application retrieves three records from the database. But it modifies only two records as shown in the below image. So only modified records are sent to the database and not all records. This optimizes the physical database trips and thus increases performance.
In simple words the final equation of unit of work is:
1 Unit of work = Modified records in a transaction
To achieve the same the first thing we need is an in-memory collection. In this collection, we will add all the business objects. Now as the transaction happens in the application they will be tracked in this in-memory collection.
Once the application has completed everything it will send these changed business objects to the database in “one transaction”. In other words either all of them will commit or all of them will fail.