Some changes make sense only as a group. If a system records a movement from one internal balance to another, saving the subtraction without the addition leaves an inconsistent result. A database transaction gives related operations a shared commit or rollback boundary.
The PostgreSQL transaction tutorial explains the all-or-nothing property and the use of BEGIN, COMMIT and ROLLBACK. This is the atomicity part of transaction behaviour; it should not be confused with every possible concurrency guarantee.
A small example reveals the boundary
Imagine an internal points system moving ten points between two accounts. Begin a transaction, check the relevant conditions, update both records and commit only when the complete operation succeeds. If the second update fails, roll back rather than leaving the first update as a completed business event.
The example is conceptual. Real applications must also handle permissions, constraints, concurrent changes and errors using the database and framework’s supported mechanisms. Merely placing two statements next to each other does not make them atomic.
The database cannot unsend an email
A frequent design mistake is to include an external action in the mental picture of the transaction. If the application sends an email and then rolls back a database change, that email has already left. A local database rollback does not reverse an unrelated service call.
Decide how external work will be coordinated. For some applications, recording a pending notification within the transaction and processing it reliably afterward is appropriate. That design also needs retry and duplicate-handling rules.
- Identify the records that must change together.
- Keep the transaction’s duration purposeful.
- Handle failure explicitly.
- Test the failure between related writes, not only the successful path.
A useful transaction boundary follows a business consistency requirement. Drawing that boundary clearly is the first step toward making partial failure predictable rather than surprising.

