Sobes.tech
Senior
51

Wie kann man doppelte Abzüge auf Ebene des Microservices und Kafka verhindern, wenn ein Kunde zweimal auf 'Auszahlung' klickt?

Unternehmen wurden gefragt
ИП Ганус Александр Андреевич

Antwort von AI

sobes.tech KI

Чтобы предотвратить двойное списание при повторном нажатии кнопки "Вывести средства" на уровне микросервиса и 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.