CodePark/ questions / Repository, unit of work & data patterns
START PRACTICINGPRACTICE
Backend question · Software design & patterns › Repository, unit of work & data patterns

What is the Unit of Work pattern, and how does it relate to transactions and repositories?

A Unit of Work is an object that tracks every change you make during one business operation. Then it writes all those changes to the database together. This is how Martin Fowler defines it. It also handles concurrency problems, which happen when two users change the same data at the same time.

Without it, every repository call goes to the database on its own. With it, the unit of work collects:

  • new objects
  • changed objects
  • deleted objects

Then it commits them together, usually in one database transaction. A transaction is a group of writes that either all succeed or all fail.

In practice, all repositories used in one use case share the same unit of work. So orders.save(order) and stock.save(item) either both commit or both roll back. ORMs often give you a unit of work already. These all play this role:

  • TypeORM's EntityManager inside a transaction
  • Entity Framework's DbContext
  • Hibernate's session

A typical shape in the application service is await uow.run(async (repos) => { ... }). This call:

  • begins the transaction
  • passes in repositories that are bound to that transaction
  • commits if everything succeeds
  • rolls back if there is an error

The business code never touches connection handling.

  • A unit of work tracks all changes made during one business operation.
  • It commits the changes together, usually in one database transaction.
  • All repositories in one use case share the same unit of work.
  • ORMs often implement it, for example EntityManager, DbContext and Hibernate's Session.
  • The application layer controls begin, commit and rollback.