Назад к вопросам
Senior
7
Клиент дважды нажал 'Вывести средства'. Как предотвратить двойное списание на уровне микросервиса и Kafka?
Компании, где спрашивали
ИП Ганус Александр Андреевич
Ответ от нейросети
sobes.tech AI
Чтобы предотвратить двойное списание при повторном нажатии кнопки "Вывести средства" на уровне микросервиса и Kafka, можно использовать следующие подходы:
- Идемпотентность операций
- Каждому запросу на вывод средств присваивается уникальный идентификатор (например, UUID или бизнес-идентификатор транзакции).
- Микросервис проверяет, была ли уже обработана операция с таким ID, и если да — игнорирует повторный запрос.
- Хранение состояния транзакции
- В базе данных хранится статус каждой операции (например, "в обработке", "успешно", "отменено").
- При повторном запросе проверяется статус, чтобы не выполнить списание повторно.
- Обработка сообщений в Kafka
- Использовать ключ сообщения (message key) равным уникальному ID операции, чтобы гарантировать порядок и идемпотентность при обработке.
- В консьюмере реализовать логику проверки и обновления статуса транзакции в атомарной операции (например, через транзакции базы данных).
- Транзакционность и блокировки
- При обработке запроса использовать механизмы блокировки или транзакции, чтобы избежать гонок.
Пример упрощённой логики на Java:
public void processWithdrawal(String operationId, BigDecimal amount) {
if (transactionExists(operationId)) {
return; // уже обработано
}
beginTransaction();
try {
reserveFunds(amount);
saveTransaction(operationId, amount, "SUCCESS");
commitTransaction();
} catch (Exception e) {
rollbackTransaction();
throw e;
}
}
Таким образом, уникальный идентификатор операции и проверка её статуса — ключ к предотвращению двойного списания при повторных запросах и повторной обработке сообщений из Kafka.