Transaction Management
Imagine you are transferring money from Account A to Account B. Two things must happen: deduct money from A, and add money to B. If the second step fails, the first step should also be undone. This is a transaction – all operations succeed together, or none succeed.
Spring provides declarative transaction management using the
@Transactional annotation. You just mark methods, and Spring handles the rest.ACID Properties of Transactions:
- Atomicity – All or nothing.
- Consistency – Data remains valid.
- Isolation – Concurrent transactions don't interfere.
- Durability – Committed changes persist.
Here is how to use @Transactional:
@Service
public class BankService {
@Autowired
private AccountRepository accountRepository;
@Transactional
public void transferMoney(Long fromAccountId, Long toAccountId, Double amount) {
Account fromAccount = accountRepository.findById(fromAccountId)
.orElseThrow(() -> new RuntimeException("Sender not found"));
Account toAccount = accountRepository.findById(toAccountId)
.orElseThrow(() -> new RuntimeException("Receiver not found"));
if (fromAccount.getBalance() < amount) {
throw new RuntimeException("Insufficient balance");
}
fromAccount.setBalance(fromAccount.getBalance() - amount);
toAccount.setBalance(toAccount.getBalance() + amount);
accountRepository.save(fromAccount);
accountRepository.save(toAccount);
// If anything fails above, everything rolls back
}
}
Transaction Attributes:
@Transactional(
propagation = Propagation.REQUIRED, // default - use existing or create new
isolation = Isolation.READ_COMMITTED, // prevent dirty reads
timeout = 30, // seconds
readOnly = false,
rollbackFor = Exception.class, // rollback on any exception
noRollbackFor = {BusinessException.class} // don't rollback for these
)
Propagation Types:
- REQUIRED – Join existing transaction or create new (default).
- REQUIRES_NEW – Always create new transaction, suspend existing.
- MANDATORY – Must run in existing transaction, throw if none.
- NEVER – Must not run in transaction, throw if exists.
- SUPPORTS – Run in transaction if exists, otherwise no transaction.
Isolation Levels:
- READ_UNCOMMITTED – Lowest, can see uncommitted changes (dirty read).
- READ_COMMITTED – Only see committed changes (prevents dirty read).
- REPEATABLE_READ – Prevents dirty read and non-repeatable read.
- SERIALIZABLE – Highest, prevents all concurrency issues (slow).
Two Minute Drill
- @Transactional ensures database operations succeed or fail together.
- ACID properties: Atomicity, Consistency, Isolation, Durability.
- Propagation defines how transactions relate to each other.
- Isolation levels control visibility of uncommitted changes.
- Use rollbackFor to specify which exceptions trigger rollback.
Need more clarification?
Drop us an email at career@quipoinfotech.com
