Sobes.tech
Назад к вопросам
Senior
7

Клиент дважды нажал 'Вывести средства'. Как предотвратить двойное списание на уровне микросервиса и Kafka?

Компании, где спрашивали
ИП Ганус Александр Андреевич

Ответ от нейросети

sobes.tech AI

Чтобы предотвратить двойное списание при повторном нажатии кнопки "Вывести средства" на уровне микросервиса и Kafka, можно использовать следующие подходы:

  1. Идемпотентность операций
  • Каждому запросу на вывод средств присваивается уникальный идентификатор (например, UUID или бизнес-идентификатор транзакции).
  • Микросервис проверяет, была ли уже обработана операция с таким ID, и если да — игнорирует повторный запрос.
  1. Хранение состояния транзакции
  • В базе данных хранится статус каждой операции (например, "в обработке", "успешно", "отменено").
  • При повторном запросе проверяется статус, чтобы не выполнить списание повторно.
  1. Обработка сообщений в Kafka
  • Использовать ключ сообщения (message key) равным уникальному ID операции, чтобы гарантировать порядок и идемпотентность при обработке.
  • В консьюмере реализовать логику проверки и обновления статуса транзакции в атомарной операции (например, через транзакции базы данных).
  1. Транзакционность и блокировки
  • При обработке запроса использовать механизмы блокировки или транзакции, чтобы избежать гонок.

Пример упрощённой логики на 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.