Implementing Transaction Management
1. Understanding ACID Properties
| Property | Meaning |
| Atomicity | All or nothing |
| Consistency | Constraints hold before/after |
| Isolation | Concurrent tx don't interfere (per level) |
| Durability | Committed data survives crash |
2. Implementing Declarative Transactions
Example: @Transactional
@Service
public class TransferService {
@Transactional
public void transfer(AccountId from, AccountId to, Money amount) {
accounts.withdraw(from, amount);
accounts.deposit(to, amount);
}
}
Warning: Spring proxies don't intercept self-invocation; calling this.method() bypasses transactional advice.
3. Implementing Programmatic Transactions
Example: TransactionTemplate
txTemplate.executeWithoutResult(status -> {
try {
accounts.withdraw(from, amount);
accounts.deposit(to, amount);
} catch (InsufficientFunds e) {
status.setRollbackOnly();
throw e;
}
});
4. Designing Transaction Boundaries
| Rule | Detail |
| One use case = one tx | Service method scope |
| Keep short | Avoid long DB locks |
| No remote calls inside | Failures hold locks |
| No user input wait | Begin only after input received |
5. Understanding Transaction Isolation Levels
| Level | Dirty Read | Non-Repeat | Phantom |
| READ UNCOMMITTED | Yes | Yes | Yes |
| READ COMMITTED | No | Yes | Yes |
| REPEATABLE READ | No | No | Yes (PG: No) |
| SERIALIZABLE | No | No | No |
6. Implementing Transaction Propagation
| Propagation | Behavior |
| REQUIRED | Join existing or create (default) |
| REQUIRES_NEW | Suspend, start new |
| NESTED | Savepoint inside outer |
| MANDATORY | Must have existing |
| SUPPORTS | Join if exists |
| NEVER | Fail if exists |
| NOT_SUPPORTED | Suspend if exists |
7. Implementing Optimistic Locking
| Mechanism | Detail |
JPA @Version | Auto-checked on update |
| Conflict | OptimisticLockException |
| Retry | Re-read, re-apply, save |
| Best for | Low contention scenarios |
8. Implementing Pessimistic Locking
Example: SELECT ... FOR UPDATE
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select a from Account a where a.id = :id")
Account lockById(@Param("id") Long id);
Warning: Always lock in consistent order to avoid deadlock.
9. Handling Transaction Rollback
| Scenario | Spring Behavior |
| RuntimeException | Rollback (default) |
| Checked exception | Commit (configure rollbackFor) |
| Manual | TransactionStatus.setRollbackOnly() |
| Caught exception | No rollback unless re-thrown |
10. Implementing Read-Only Transactions
| Benefit | Detail |
| Hibernate skip dirty check | Performance |
| DB hint | May route to replica |
| Prevent accidental writes | Safer query methods |
Example: read-only flag
@Transactional(readOnly = true)
public List<Order> search(OrderFilter f) { ... }
11. Understanding Distributed Transactions
| Pattern | Trade-off |
| 2PC (XA) | Strong; slow, blocking |
| Saga (orchestration) | Eventual; central coordinator |
| Saga (choreography) | Eventual; via events |
| Outbox + idempotent consumer | Reliable event publish |
12. Implementing Savepoints
Example: Nested rollback
@Transactional
public void process(List<Item> items) {
for (Item i : items) {
try { txTemplate.execute(s -> { processOne(i); return null; }); }
catch (Exception e) { failed.add(i); } // outer continues
}
}