Ответ
Для финансовых операций, таких как перевод, требуется уровень изоляции, предотвращающий аномалии, которые могут привести к потере или "дублированию" денег.
Рекомендуемые уровни:
REPEATABLE_READ— стандартный выбор. Гарантирует, что данные, прочитанные в транзакции (например, баланс счета), не изменятся другими транзакциями до её завершения. Предотвращает грязное и неповторяемое чтение.SERIALIZABLE— максимальная защита. Требуется в сценариях с экстремальной конкуренцией, когда необходимо также предотвратить фантомное чтение (например, если в логике есть агрегатные запросы по всем счетам). Снижает производительность.
Пример (Spring Boot с REPEATABLE_READ):
@Service
public class TransferService {
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void transfer(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));
// Сохранение происходит при коммите транзакции
}
}