@Transactional(readOnly = true)?Многие добавляют
@Transactional(readOnly = true) на сервисные методы просто по привычке. Но давайте разберёмся, что на самом деле даёт этот флаг, и где он реально ускоряет выполнение.📌 Что делает
readOnly = true?* Подсказывает JPA провайдеру (например, Hibernate), что изменения в сущностях можно не отслеживать (
skip dirty checking).* В некоторых БД может выставить read-only transaction flag, который предотвращает нежелательные изменения (например, в PostgreSQL).
* Может ускорить выборки, особенно при больших графах сущностей.
💡 Пример:
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
@Transactional(readOnly = true)
public UserDto getUser(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("User not found"));
return UserDto.from(user);
}
}
⚠️ Важно:
*
readOnly = true не блокирует изменения в БД, если вы явно вызываете save() — это НЕ защита от дурака.* Hibernate всё равно создаст транзакцию — это не аннотация "без транзакций".
✅ Когда использовать:
* Методы, которые только читают данные и не модифицируют сущности.
* Большие выборки без нужды в lazy-инициализации через сессию.
* Там, где критична производительность чтения.
❌ Когда НЕ нужно:
* Если вы всё равно модифицируете сущности внутри метода.
* Если работаете с
@Modifying запросами — Spring их игнорирует при readOnly = true.📎 Документация Spring @Transactional
👉 @java_geek