Идемпотентность — это свойство операции, при котором повторная отправка одного и того же запроса не создаёт вторую запись. Отправили заказ один раз — создался один документ. Отправили тот же самый заказ пять раз подряд — документ по-прежнему один, а на четыре лишние попытки система ответила «этот уже принят». Всё остальное в этой статье — про то, во что превращается наличие или отсутствие этого свойства в деньгах.
Офисная аналогия у термина есть, и она старше любых интеграций — платёжное поручение. Бухгалтер отправил платёж в банк-клиент, связь оборвалась, статуса нет. Он отправляет ещё раз, и второго списания не происходит: банк смотрит на номер и дату поручения и видит, что такой документ уже принят. Именно поэтому у платёжки есть номер, а не только сумма и получатель. Номер платёжного поручения — это и есть ключ идемпотентности, придуманный задолго до появления слова.
Дальше — три симптома отсутствия защиты, модельный расчёт по состоянию на сентябрь 2026 года и сценарий приёмки. Компания в примере: дистрибьютор упаковочных материалов, 45 человек, три обмена — сайт с CRM, CRM с 1С:УТ и 1С со службой доставки. Через них проходит около 2 000 операций в месяц. Ставка инженера — 3 000 ₽/час, полная стоимость часа менеджера — 900 ₽, бухгалтера — 844 ₽, кладовщика — 550 ₽, оператора поддержки — 700 ₽.
Повтор — не сбой, а обязанность отправителя
Главное недоразумение вокруг этого термина: кажется, что дубль — следствие ошибки в программе. На самом деле дубль возникает при полностью правильном поведении обеих сторон. Отправитель послал заказ, связь оборвалась после отправки, но до ответа. Он не знает, доехал документ или нет. Единственное безопасное поведение — послать ещё раз: если не послать, заказ потеряется навсегда, и это хуже. Значит, повторы будут всегда, и вопрос только в том, готов ли к ним приёмник.
Свойство операции, при котором её повторное выполнение с теми же данными не меняет результат. Бизнесу нужна везде, где операция что-то создаёт или списывает: заказ, счёт, платёж, движение по складу, письмо клиенту. В смете — отдельная строка на 12–20 часов в каждом обмене, где такие операции есть. Проверочный вопрос подрядчику: что произойдёт, если ваш запрос отправить дважды подряд.
Уникальная строка, которую отправитель формирует один раз на событие и подставляет во все повторы. Приёмник хранит список принятых ключей и на повтор отвечает «уже принято» вместо создания второго документа. В соседнем разборе механики дублей показано, почему такой список хранят 30–90 дней: раньше — повтор из карантина создаст дубль, дольше — таблица разрастается без пользы.
Отсюда и практическое следствие. Фраза «мы всё проверим и дублей не будет» ничего не значит: проверка — это и есть работа, за которую платят, а не обещание аккуратности. Проверка бывает только одна — сопоставление по ключу, и она либо заложена в смету, либо нет.
Три симптома, по которым видно отсутствие защиты
Владелец бизнеса про идемпотентность не спрашивает — он приходит с одной из трёх жалоб. Все три означают одно и то же.
- 1В CRM две одинаковые сделки
Одна заявка, две карточки, разные ответственные, и клиенту звонят двое. Менеджер тратит 20 минут на то, чтобы понять, какая настоящая, слить историю и закрыть лишнюю. В модельной компании это 5 случаев в месяц. Ситуация обостряется, когда распределение заявок работает автоматически: система успевает назначить исполнителя на обе карточки раньше, чем человек заметит дубль.
- 2Клиенту ушло два одинаковых письма
Самый безобидный на вид симптом и самый заметный снаружи. Повторное уведомление о заказе или о смене статуса выглядит как неаккуратность компании; часть клиентов на него отвечает и создаёт обращение в поддержку. Четыре случая в месяц, по 15 минут оператора на разбор каждого.
- 3Товар списался со склада дважды
Самый дорогой из трёх. Остаток в системе становится меньше фактического, товар «продан» дважды, и расхождение всплывает не сразу, а на инвентаризации или на следующем заказе, когда система показывает ноль при полной полке. Разбор одного случая — 40 минут кладовщика, 20 минут менеджера и 20 минут бухгалтера на сторно.
Горизонтальная схема из двух дорожек между блоками «Отправитель» слева и «Приёмник» справа. Верхняя дорожка: стрелка «заказ, ключ A-4471» доходит до приёмника, дальше блок «Создан документ», обратная стрелка «ответ» оборвана зигзагом с подписью «связь потеряна». Нижняя дорожка: та же стрелка «повтор, ключ A-4471», далее ромб «Ключ уже в журнале?» с двумя выходами: «да → ответ «уже принято», документ не создаётся» и «нет → создать документ». Сбоку небольшой блок «Журнал принятых ключей, хранение 30–90 дней». Тонкие чертёжные линии, подписи по-русски.
Сколько стоит отсутствие защиты и сколько — её наличие
В модельной компании повторная доставка случается примерно в 0,6 % операций — это 12 дублей в месяц на потоке в 2 000 операций. Отдельно считаем редкий, но дорогой случай: примерно раз в квартал дубль не ловят вовремя и по нему уезжает вторая отгрузка.
Обратите внимание на структуру суммы: три частых симптома дают 4 096 ₽, а один редкий — 4 563 ₽, то есть больше половины. Это типичная форма ущерба от дублей и главная причина, по которой их годами терпят: в обычный месяц ничего страшного не происходит, а раз в квартал случается история, которую списывают на человеческий фактор.
Столбчатая диаграмма из четырёх столбцов, ось Y в рублях до 5 000. Столбцы подписаны: «Сделки в CRM — 1 500 ₽», «Письма клиенту — 700 ₽», «Списания со склада — 1 896 ₽», «Отгрузка по дублю (раз в квартал) — 4 563 ₽». Четвёртый столбец выделен более плотной заливкой и подписан «редкий, но дороже трёх остальных вместе». Сверху общая подпись «8 659 ₽ в месяц». Тонкие чертёжные линии, подписи по-русски.
Один вопрос подрядчику и четыре варианта ответа
Вопрос формулируется дословно так: «Что произойдёт, если ваш запрос отправить дважды подряд?» Он занимает десять секунд и отсеивает больше, чем страница технических требований, потому что ответить на него общими словами трудно.
| Ответ подрядчика | Что он означает | Что делать дальше |
|---|---|---|
| «Создадутся два документа, поэтому нужен ключ операции — вот как мы его формируем» | Защита продумана и, скорее всего, уже заложена | Попросить показать строку в смете и срок хранения списка принятых ключей |
| «Такого не бывает, мы отправляем один раз» | Повторы не рассматривались вовсе; при первом же обрыве связи появится дубль | Считать защиту не заложенной и обсуждать отдельно, до подписания |
| «Мы проверяем по номеру заказа» | Работает, если номер рождается в первой системе на пути и не меняется по дороге | Уточнить, где именно рождается номер и что происходит с заказами без номера |
| «Настроим сверку и найдём дубли потом» | Сверка нужна, но она находит дубль после того, как он создан и по нему уже поработали | Оставить сверку как второй слой, а ключ операции добавить как первый |
Отдельно стоит понимать, почему проблема обостряется на событийном обмене. При обмене по расписанию система забирает список записей и сама решает, каких у неё ещё нет. При вебхуках инициатива у отправителя: он не получил подтверждение и повторяет доставку сам, часто несколько раз с нарастающей паузой. То же самое делает и очередь с повторными попытками на вашей стороне — механизм, который спасает от потерь, одновременно является главным поставщиком повторов. Поэтому очередь и защита от дублей закладываются в смету парой, а не по отдельности.
Приёмка без программиста: четыре шага
Этот сценарий выполняет сотрудник заказчика при подрядчике, занимает около получаса и не требует технических навыков. Результат каждого шага виден в обычном интерфейсе.
- 1Оформите один заказ обычным путём и запишите его номер во всех системах цепочки. Это контрольная точка: дальше числа должны сравниваться с ней, а не с ощущением.
- 2Попросите подрядчика при вас нажать «повторить отправку» в журнале обмена для этого же заказа. Новых документов появиться не должно, а в журнале обмена должна появиться запись со статусом вроде «уже принято». Если запись появилась, а документ создался — защиты нет.
- 3Отправьте форму заказа на сайте дважды подряд: нажмите кнопку второй раз или обновите страницу подтверждения. Второй заказ создаваться не должен. Этот шаг проверяет начало цепочки, которое чаще всего забывают.
- 4Попросите показать, где хранится список принятых ключей и за какой срок. Правильный ответ — конкретная таблица и срок в диапазоне 30–90 дней. Ответ «где-то в логах» означает, что список не ведётся, а совпадения ищутся вручную по факту жалобы.
Когда защита от повторов не нужна
Строка на 45 000 ₽ оправдана не всегда, и вычёркивать её иногда правильно. Три случая, когда это так.
- Операция ничего не создаёт и не списывает. Обновление статуса, перезапись остатка целым числом, синхронизация справочника — здесь повтор безвреден по природе: второе выполнение приводит к тому же результату, что и первое. Защита нужна там, где операция добавляет запись, а не заменяет её.
- Поток меньше 200 операций в месяц и все документы проходят через человека. При таком объёме дубль заметят в тот же день, а годовая цена ущерба окажется меньше стоимости самой защиты. Разумнее ограничиться сверочным отчётом раз в неделю.
- Обмен односторонний и идёт файлом раз в сутки. Здесь повторов не возникает вовсе: файл либо забрали, либо нет. Платить за ключ операции в такой схеме не за что — но стоит помнить, что при переходе на событийный обмен эта строка появится, и появится обязательно.
И обратное правило: если по операции автоматически уходит письмо клиенту, списывается товар или создаётся расходный документ, защита обязательна независимо от объёма. Один дубль в такой цепочке стоит дороже, чем вся строка сметы, и в модельном расчёте выше это видно по последней позиции.
Повтор запроса — не авария, а нормальное поведение исправной системы. Аварией он становится там, где приёмник не умеет узнавать то, что уже принимал.
