Java
Сложный
Как работает аннотация @Transactional?
@Transactional в Spring
Как работает:
Spring создаёт proxy вокруг класса/метода:
@Service
public class UserService {
@Transactional
public void createUser(User user) {
userRepository.save(user);
auditService.log("User created");
}
}
Proxy делает:
- Открывает транзакцию
- Вызывает метод
- Commit при успехе / Rollback при исключении
Параметры:
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
timeout = 30,
readOnly = false,
rollbackFor = Exception.class,
noRollbackFor = BusinessException.class
)
Propagation (распространение):
| Тип | Описание |
|---|---|
| REQUIRED | Использовать текущую или создать новую |
| REQUIRES_NEW | Всегда новая (приостанавливает текущую) |
| NESTED | Вложенная (savepoint) |
| SUPPORTS | Использовать если есть, иначе без |
| NOT_SUPPORTED | Выполнять без транзакции |
| MANDATORY | Требует существующую |
| NEVER | Ошибка если есть транзакция |
Isolation (изоляция):
@Transactional(isolation = Isolation.SERIALIZABLE)
public void criticalOperation() { }
- READ_UNCOMMITTED — dirty reads
- READ_COMMITTED — нет dirty reads
- REPEATABLE_READ — нет non-repeatable reads
- SERIALIZABLE — полная изоляция
Типичные ошибки:
1. Self-invocation (не работает):
@Service
public class UserService {
public void methodA() {
methodB(); // @Transactional НЕ сработает!
}
@Transactional
public void methodB() { }
}
// Решение: вынести в другой сервис или использовать self-injection
2. Checked exceptions (не откатывают):
@Transactional // По умолчанию откатывает только RuntimeException
public void process() throws IOException {
// IOException не откатит транзакцию!
}
// Решение:
@Transactional(rollbackFor = Exception.class)
3. Private методы:
@Transactional // НЕ работает на private!
private void privateMethod() { }
Best Practices:
- Используйте на уровне сервисов, не репозиториев
- Делайте транзакции короткими
- Указывайте readOnly=true для чтения
- Логируйте откаты
@Transactional(readOnly = true)
public List<User> getUsers() {
return userRepository.findAll();
}
Похожие вопросы
Готовитесь к собеседованию?
ENIGMA AI — невидимый ИИ-помощник для технических интервью
Попробовать бесплатно