Self-invocation: method gọi method khác trong cùng class → @Transactional bị bỏ qua.
Spring transaction chạy qua AOP proxy — proxy bọc bean, chặn call từ ngoài để begin/commit. Gọi this.B() đi thẳng vào object, không qua proxy → annotation trên B vô hiệu.
java
@Service
class OrderService {
public void processOrders(List<Long> ids) {
ids.forEach(id -> processOne(id)); // ❌ self-invocation → không có transaction
}
@Transactional
public void processOne(Long id) { ... }
}Fix: tách processOne sang service khác rồi inject (cách đúng); hoặc self-inject proxy (@Lazy @Autowired OrderService self; rồi gọi self.processOne(id)).
Nguyên tắc: @Transactional chỉ có hiệu lực với public method gọi từ ngoài bean. @Async, @Cacheable cũng dính lỗi self-invocation này.