Защита от повторного запроса с помощью бд

Идемпотентный метод

Метод HTTP является идемпотентным, если повторный идентичный запрос, сделанный один или несколько раз подряд, имеет один и тот же эффект, не изменяющий состояние сервера. Другими словами, идемпотентный метод не должен иметь никаких побочных эффектов (side-effects), кроме сбора статистики или подобных операций.

Корректно реализованные методы GET, HEAD, PUT и DELETE идемпотентны, но не метод POST. Также все безопасные методы являются идемпотентными.

Факты об идемпотентности

  • Для идемпотентности нужно рассматривать только изменение фактического внутреннего состояния сервера.
  • Возвращаемые запросами коды статуса могут отличаться: первый вызов DELETE вернёт код 200, в то время как последующие вызовы вернут код 404.
  • Из идемпотентности DELETE неявно следует, что разработчики не должны использовать метод DELETE при реализации RESTful API с функциональностью удалить последнюю запись.

Пример запросов

  • GET /pageX HTTP/1.1 идемпотентен.
  • POST /add_row HTTP/1.1 не идемпотентен.
  • DELETE /idX/delete HTTP/1.1 идемпотентен.

Материалы для изучения

Если вы разрабатываете Веб-приложение или REST-сервис, то рано или поздно столкнётесь с повторными запросами. Что имеется в виду? Объясню на примере Веб-страницы с кнопкой. По нажатию на кнопку, на бэкенд отправляется запрос. Запрос, соответственно, синхронный и пока серверная часть делает какую-то работу, браузер клиента показывает, что загружает страницу. Если это происходит продолжительное время, клиент может подумать, что его запрос завис и нажать кнопку ещё раз. Также повторное нажатие может произойти случайно.

Пример нежелательного дублирования запросов

  • В интернет-магазине создаётся заказ на оплату.
  • При нажатии кнопки оплатить, с клиента списываются деньги и меняется статус заказа.
  • Двойное нажатие кнопки может привести к списанию денег дважды из-за одного заказа.
Про сертификаты:  Имеет ли право жена при разводе на квартиру,приобретенную в браке по военному жилищному сертификату? - Правовед.RU

Возможные проблемы

  • Два запроса могут прийти практически одновременно и оба обработать одну и ту же запись из БД.
  • Оба запроса могут изменить состояние заказа, приводя к ошибкам в логике приложения.
## Решение проблемы с обновлением статуса

Решим эту проблему с помощью базы данных. Так как БД делает изменения атомарно, то используем это для решения нашей проблемы.

## Шаг 1: Запрос к базе данных

Принцип такой: мы пытаемся выполнить в БД запрос на обновление статуса с условием, что запись имеет статус REGISTERED. Запрос должен также вернуть количество обновлённых записей.

## Шаг 2: Проверка в Java коде

Далее, уже в Java коде, нам нужно проверить, сколько записей обновилось. Если количество обновлённых записей равно 1, то запрос выполнен успешно. Это означает, что мы можем сделать перечисление денег. Если количество обновлённых записей равно 0, это означает, что кто-то уже успел обновить запись до нас и деньги списывать не нужно.

## Обновленный код

Далее изменим наш первоначальный код в соответствии с указанным алгоритмом. Такой простой способ поможет избежать неприятных ошибок.

Оцените статью
Мой сертификат
Добавить комментарий