Concept Flow - Transactions
Start Transaction
Execute DB Operations
Check for Errors
Commit
End Transaction
This flow shows how a transaction starts, runs database operations, then commits if all is good or rolls back if errors occur.
await this.dataSource.transaction(async manager => { await manager.save(user); await manager.save(profile); });
| Step | Action | Operation | Result | Transaction State |
|---|---|---|---|---|
| 1 | Start transaction | Begin transaction | Transaction started | Active |
| 2 | Save user | Insert user record | User saved | Active |
| 3 | Save profile | Insert profile record | Profile saved | Active |
| 4 | No errors detected | Check operations | All successful | Active |
| 5 | Commit transaction | Commit changes | Transaction committed | Committed |
| 6 | End transaction | Close transaction | Transaction ended | Committed |
| Variable | Start | After Step 2 | After Step 3 | Final |
|---|---|---|---|---|
| transactionState | None | Active | Active | Committed |
| userSaved | False | True | True | True |
| profileSaved | False | False | True | True |
Transactions in NestJS:
- Use dataSource.transaction(async manager => {...})
- All DB ops inside run atomically
- If all succeed, transaction commits
- If any fail, transaction rolls back
- Keeps data consistent and safeawait dataSource.transaction(async (manager) => {
await manager.save(user1);
await manager.save(user2); // throws error
});
console.log('Transaction complete');await dataSource.transaction(async (manager) => {
manager.save(user1);
await manager.save(user2);
});async updateEntities(entityA, entityB) {
await this.dataSource.transaction(async (manager) => {
await manager.save(entityA);
await manager.save(entityB);
});
}
What is the best practice to handle errors and maintain data consistency?Pass the test and this pattern moves unknown