Unit of Work Pattern
Unit of Work: separate a useful responsibility
See the responsibility boundary
One operation changes a customer record and an order. Saving each change immediately can leave a partial result. The code needs a clear boundary for the changes that belong to one supported transaction.
This application-pattern lesson connects local organization with the system contracts discussed elsewhere in the course. The code is an original small local example, not a production persistence or web framework.
What you’ll learn
- Explain the responsibility Unit of Work separates.
- Follow its local example and identify the implementation boundary.
- Compare related patterns and test the required guarantees.
How the responsibility is divided
Unit of Work tracks changes associated with a business operation and coordinates their persistence under a defined commit boundary. Implementations can track changed entities, stage explicit operations or integrate with an ORM’s transaction/session mechanism.
The example stages updates and produces a new in-memory Map at commit. It demonstrates a grouping boundary only. A database implementation must use its supported transaction rather than copying this as an atomic multi-service protocol.
Follow a small JavaScript example
Read the program and compare the expected output. Its state is local to one execution context; a real implementation needs the persistence, request and effect contracts described in the trade-offs.
JavaScript · local teaching example
let store = new Map([['customer', 'old'], ['order', 'draft']]);
const staged = new Map();
staged.set('customer', 'updated');
staged.set('order', 'submitted');
function commit() {
const next = new Map(store);
for (const [key, value] of staged) next.set(key, value);
store = next;
}
console.log(store.get('order'));
commit();
console.log(store.get('order'));Expected output
draft
submittedChoose a boundary from the situation
Compare boundary choices
Compare the visible consequences. With JavaScript enabled, choose an option in each scenario to assemble your decision record.
This is an exploratory design exercise. It does not run infrastructure, measure capacity or replace the lesson’s quiz.
All alternatives and consequences remain visible. Select one per situation to record your reasoning.
Choose it for a concrete need
Use it to make transaction ownership and grouped persistence explicit, especially when related repositories participate in the same supported store transaction.
Long-lived units can hold locks or stale tracked objects. Define commit errors, conflict retries and cleanup. A local Unit of Work cannot make unrelated databases, a payment API and a broker one atomic resource merely because the calls are grouped.
Compare the neighbouring responsibilities
Repository supplies domain-oriented access. Unit of Work coordinates persistence for an operation. Saga handles multi-owner local commits through a business recovery contract.
Continue with domain-oriented persistence access, recovery across separate owners, transaction isolation and invariants.
For primary further reading, use the Unit of Work catalog entry and compare the responsibilities with this course’s original example.
Check your pattern reasoning
Check your pattern reasoning
Keep the boundary and its guarantees explicit
Use Unit of Work when its responsibility matches the actual problem. Keep implementation lifetime, concurrency and error behaviour visible rather than treating an organizational label as proof.
Return to the design-pattern guide or apply this alongside transaction isolation and invariants.
Reaching the recap and completing the quizzes are separate milestones.