Spring Boot · Lesson 8 of 15
Transactions and Locking
@Transactional boundaries, isolation and optimistic locking.
- Intermediate
- 16 min read
- 3 objectives
Before this lessonLesson 7: Validation and Problem Details
What you will learn
- Mark a service transactional
- Use @Version
- Avoid self-invocation
Your Progress
0 of 15 lessons 0%
- Lessons0 / 15
- Completed0
- Est. time left~ 4 hours
Create a free account to keep your progress on every device.
@Transactional wraps a method in a database transaction. It only works when called through the Spring proxy, on a public method, from another bean.
Where it belongs
@Service
public class TransferService {
private final AccountRepository accounts;
@Transactional
public void transfer(long fromId, long toId, long cents) {
Account from = accounts.findByIdForUpdate(fromId).orElseThrow();
Account to = accounts.findByIdForUpdate(toId).orElseThrow();
from.debit(cents);
to.credit(cents);
}
}Keep transactions on the service layer, not on controllers, and as short as possible. Do not call HTTP inside one.
Optimistic locking
@Entity
public class Product {
@Id @GeneratedValue Long id;
long stock;
@Version long version;
}A stale update throws OptimisticLockException. Catch it and retry, or tell the user to refresh.
