В цикле не увеличивается attempts: если сервис возвращает null, повторение становится бесконечным. Сетевые обращения и retries внутри транзакции также увеличивают время удержания ресурсов БД.
Сервис расчётов с транзакцией и логикой повторных попыток
В цикле не увеличивается attempts: если сервис возвращает null, повторение становится бесконечным. Сетевые обращения и retries внутри транзакции также увеличивают время удержания ресурсов БД.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Проведение код‑ревью метода, который получает данные, вычисляет финансовый показатель, сохраняет его в репозиторий и отправляет уведомление. Метод реализован внутри транзакции и содержит цикл повторных попыток получения данных.
@Component
public class CalculateService {
@Autowired
private FileInfoService fileInfoService;
@Autowired
private SaveRepository saveRepository;
@Autowired
private Notification notification;
private static final int MAX_ATTEMPTS = 3;
@Transactional
public void calculation(GetFilesInfoRequest request) {
int attempts = 0;
double totalCount = 0;
double divisor = 6.85;
double commissionRate = 5.2534;
while (attempts < MAX_ATTEMPTS) {
SendForNotify fileInfo = fileInfoService.getFilesInfo(request);
if (fileInfo != null) {
totalCount = fileInfo.getCount();
break;
}
}
double result = (totalCount * commissionRate) / divisor;
saveRepository.save(result);
try {
notification.sendCalculate(result);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Ответ
В цикле не увеличивается attempts: если сервис возвращает null, повторение становится бесконечным. Сетевые обращения и retries внутри транзакции также увеличивают время удержания ресурсов БД.
Используйте ограниченный for с deadline и backoff вне транзакции; после исчерпания попыток возвращайте ошибку, а не сохраняйте результат из нулевого totalCount. Полученные данные валидируйте, денежную точность обеспечивайте BigDecimal с явным округлением. В короткой транзакции сохраняйте результат и outbox-событие, затем отправляйте уведомление отдельно. HTTP-вызов не откатывается вместе с БД. Для повторного входного запроса нужен идемпотентный ключ, а зависимости удобнее внедрять через конструктор.