← Назад к вопросам
Как работает транзакция в Spring Data JPA?
2.0 Middle🔥 241 комментариев
#ORM и Hibernate#Spring Boot и Spring Data
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает транзакция в Spring Data JPA?
Транзакция — это набор операций с базой данных, которые либо все выполняются успешно (commit), либо все откатываются (rollback). Spring Data JPA управляет транзакциями автоматически через аннотацию @Transactional.
Основной механизм
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public void createUser(String email, String name) {
User user = new User();
user.setEmail(email);
user.setName(name);
userRepository.save(user);
}
}
Жизненный цикл транзакции
1. Начало транзакции (BEGIN TRANSACTION)
2. Выполнение SQL операций
3a. Успех - COMMIT
3b. Ошибка - ROLLBACK
4. Закрытие соединения с БД
Уровни изоляции
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void operation1() { }
@Transactional(isolation = Isolation.READ_COMMITTED)
public void operation2() { }
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void operation3() { }
@Transactional(isolation = Isolation.SERIALIZABLE)
public void operation4() { }
Тип пропагации
@Transactional(propagation = Propagation.REQUIRED)
public void save(User user) { }
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logAction(String action) { }
@Transactional(propagation = Propagation.SUPPORTS)
public User findById(Long id) { }
Управление откатом
@Transactional(
rollbackFor = Exception.class,
noRollbackFor = ValidationException.class
)
public void processPayment(Payment payment) throws Exception {
paymentRepository.save(payment);
}
ReadOnly флаг
@Transactional(readOnly = true)
public List<User> getAllUsers() {
return userRepository.findAll();
}
Timeout
@Transactional(timeout = 10)
public void heavyOperation() {
}
Вложенные транзакции
@Service
public class UserService {
@Autowired
private AuditService auditService;
@Transactional
public void registerUser(String email) {
auditService.logAudit("User created");
}
}
@Service
public class AuditService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logAudit(String message) { }
}
Пример transfer денег
@Service
public class BankService {
@Autowired
private AccountRepository accountRepository;
@Transactional(isolation = Isolation.SERIALIZABLE)
public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
Account from = accountRepository.findById(fromId).orElseThrow();
Account to = accountRepository.findById(toId).orElseThrow();
if (from.getBalance().compareTo(amount) < 0) {
throw new InsufficientFundsException();
}
from.setBalance(from.getBalance().subtract(amount));
to.setBalance(to.getBalance().add(amount));
accountRepository.save(from);
accountRepository.save(to);
}
}
Важные моменты
- Spring использует AOP для интерцепции методов с @Transactional
- Только на публичных методах работает, приватные методы не управляются
- Внутренний вызов через this не создаёт прокси
- Checked exceptions НЕ вызывают rollback по умолчанию
- RuntimeExceptions вызывают rollback автоматически
Оптимизация
- Минимизируй scope — только необходимые операции
- Используй readOnly для чтения — улучшает производительность
- Выбирай правильный isolation level — баланс между безопасностью и скоростью
- Избегай deadlock — консистентный порядок доступа
- Кэшируй данные — снизь нагрузку на БД
Транзакции в Spring Data JPA обеспечивают целостность данных и атомарность операций.