++ Статья*** описывает проблему гарантии полноты и неизбыточности при последовательной установке двух состояний;
*** выдвигает гипотезу о невозможности разрешения проблемы без участия состояний (без идемпотентности состояний);
*** предлагает Общее решение.
++ Задача
*** Поток T должен установить два состояния S1 и S2.
*** S1 и S2 возвращают синхронный ответ при успехе сохранения и не более.
*** Требуется гарантировать полноту и не избыточность установки состояний.
++ Проблема
*** Поток Т выполняет запись в S1.
*** При провале поток Т возвращает отказ.
*** При успехе поток Т должен выполнить запись в S2.
*** Начиная с этого момента возникает проблема неопределенности при ошибке установки S2 или крахе потока Т, состояние S1 уже установлено, а S2 не установлено; однозначно не определен результат исполнения потока T; повторный вызов потока Т не разрешит ситуацию.
++ Гипотеза
Не существует решения при котором поток Т гарантирует полноту и неизбыточность установки двух состояний, при том что состояния возвращают исключительно синхронный ответ о результате сохранения.
Никакие механизмы со стороны Т не могут разрешить указанную проблему без идемпотентности S1.
++ Варианты решения
*** Состояние S1 должно быть идемпотентным например: защита от дублированного получения данных; возможность оповещения T по его инициативе о результатах сохранения.
*** T должен обладать возможностью повтора установки состояний при отказе.
[[IMG /opennews/pics_base/CFD0C5CECEC5D4_1728724620.png]]
++ Общее решение гарантии консистентности состояний
Ниже перечислены рассматриваемые виды состояний:
*** S - (simple state) простое состояние без поддержки транзакций и идемпотентности, например: очереди сообщений (kafka, итд); внешние сервисы; базы без идемпотентных проверок, с триггерами или автокоммитом; журналирование.
*** I - (idempotent state) - состояние с поддержкой идемпотентности: базы данных; сервисы; файлы.
*** T - (transact state) - состояния, поддерживающие транзакционную целостность: базы данных TSQL.
++ Возможные комбинации
Далее приведены возможные комбинации последовательной установки состояний в синхронном потоке, гарантия итоговой консистентности для различных вариантов и последствия сбоя в потоке между установкой состояний.
Обязательным условием является повтор вызова потока при отказе на любой стадии.
Пример:
Поток получает сообщение из очереди, которая гарантирует повторяемость.
Вызов потока из UI не гарантирует повторяемость события, так как пользователь получив ошибку, может не выполнить повторное действие.
++ SS
*** Гарантия консистентности: нет
*** Пример: Push сообщения в очередь; Write в журнал
*** Последствия: Накопление дублей сообщений в очереди
++ SI
*** Гарантия консистентности: нет
*** Пример: Commit сообщения очереди; Идемпотентный вызов сервиса
*** Последствия: Отсутствие гарантии вызова сервиса
++ ST
*** Гарантия консистентности: нет
*** Пример: Commit сообщения очереди; Insert в базу
*** Последствия: Накопление дублей сообщений в очереди
++ IS
*** Гарантия консистентности: да
*** Пример: Insert с предпроверкой в базу; Commit сообщения очереди
*** Последствия: Многократные попытки Insert
++ II
*** Гарантия консистентности: да
*** Пример: Insert с предпроверкой в базу; Update с предпроверкой в базу
*** Последствия: Многократные попытки Insert
++ IT
*** Гарантия консистентности: да
*** Пример: Вызов внешнего сервиса; Запись в базу
*** Последствия: Многократный вызов внешнего сервиса
++ TS
*** Гарантия консистентности: нет
*** Пример: Insert в базу; Push в очередь
*** Последствия: Накопление дублей в БД
++ TI
*** Гарантия консистентности: нет
*** Пример: Insert в базу; Запись с предпроверкой в базу
*** Последствия: Накопление дублей в БД
++ TT
*** Гарантия консистентности: нет
*** Пример: Insert в базу; Запись в базу в одной транзакции
*** Последствия: Полный откат транзакции
++ Общие правила гарантии сохранения состояний
Повторяемость вызова при любом отказе в потоке
И идемпотентность предыдущего изменения состояния
ИЛИ изменение всех состояний в единой транзакции.
++ Ccылки
[[https://github.com/johnthesmith/scraps/blob/main/ru/state_co... статья на github]]
URL:
Обсуждается: http://www.opennet.me/tips/info/3256.shtml