Гарантия консистентности двух и более состояний |
[исправить] |
Статья
описывает проблему гарантии полноты и неизбыточности при последовательной
установке двух состояний;
выдвигает гипотезу о невозможности разрешения проблемы без участия
состояний (без идемпотентности состояний);
предлагает Общее решение.
Задача
Поток T должен установить два состояния S1 и S2.
S1 и S2 возвращают синхронный ответ при успехе сохранения и не более.
Требуется гарантировать полноту и не избыточность установки состояний.
Проблема
Поток Т выполняет запись в S1.
При провале поток Т возвращает отказ.
При успехе поток Т должен выполнить запись в S2.
Начиная с этого момента возникает проблема неопределенности при ошибке
установки S2 или крахе потока Т, состояние S1 уже установлено, а S2 не
установлено; однозначно не определен результат исполнения потока T; повторный
вызов потока Т не разрешит ситуацию.
Гипотеза
Не существует решения при котором поток Т гарантирует полноту и неизбыточность
установки двух состояний, при том что состояния возвращают исключительно
синхронный ответ о результате сохранения.
Никакие механизмы со стороны Т не могут разрешить указанную проблему без идемпотентности S1.
Варианты решения
Состояние S1 должно быть идемпотентным например: защита от дублированного
получения данных; возможность оповещения T по его инициативе о результатах сохранения.
T должен обладать возможностью повтора установки состояний при отказе.
Общее решение гарантии консистентности состояний
Ниже перечислены рассматриваемые виды состояний:
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ылки
статья на github
|
|
|
|
Раздел: Корень / Программисту и web-разработчику / Системы контроля версий и управления исходными текстами |