Обеспечение атомарности

Sufir

Я не волшебник, я только учусь
Есть ряд действий выполняемых пользователями, в рамках которых все операции должны выполняться корректно, либо не выполняться вообще.
В частности это некоторое кол-во запросов к БД от двух, логирование, взаимодействие со сторонними сервисами (JSON-RPC), при некоторых условиях отправка электронки и т.п.

С БД всё просто, в транзакцию обернул и всё. Но, к примеру с RPC сложности. Т.е. если я сначала выполняю процедуру RPC и она завершается некорректно, то дальше и в БД ничего не пишется. Если же запрос к RPC выполняется корректно и далее происходит ошибка, то тут уже не откатишь.

В общем есть несколько мыслей, но хотелось бы узнать о возможных подходах.
 

WMix

герр M:)ller
Партнер клуба
лучше "несколько мыслей" для начала
 

Hello

Новичок
Sufir, делать не откатываемые операции в последний момент.
Если удалил файл, отправил email или отправил bitcoin, то ничего уже не поделать.
 

Sufir

Я не волшебник, я только учусь
лучше "несколько мыслей" для начала
Одна из:
делать не откатываемые операции в последний момент.
Сейчас так делаю. Посмотрю будет ли результат удовлетворительным. Тут сложность с тем, что не откатываемых операций может быть более одной в одном действии. Есть некритические (для меня), например, если письмо в конце всего не отправится - не беда. Но могут быть и ключевые. В частности две и более процедуры RPC подряд.

Еще думал о варианте с задачами. Грубо говоря действие пользователя создеет задачу, а каждая операция представлена подзадачей. И пытаться выполнить задачу, отмечая выполненные операции, пока все выполнены не будут.
Задержка всё же менее критична, чем вообще нарушение целостности.
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
Sufir, делать не откатываемые операции в последний момент.
Если удалил файл, отправил email или отправил bitcoin, то ничего уже не поделать.
еслиб было все так просто, а если RPC изменяет удаленно, и возвращает нечто от чего зависят следующие операции? сам думаю об этом, поэтому и интересуюсь.
 

Sufir

Я не волшебник, я только учусь
еслиб было все так просто, а если RPC изменяет удаленно, и возвращает нечто от чего зависят следующие операции? сам думаю об этом, поэтому и интересуюсь.
У меня благо на данный момент порядок операций значения не имеет, но тоже проблема. В общем вполне нормальный вариант, если порядок не имеет значения и не откатываемая операция только одна. Т.е. условия очень уж узкие.
 

Adelf

Administrator
Команда форума
Ты реально думаешь, что есть решение, позволяющее откатить неоткатываемую операцию? :)
 

Adelf

Administrator
Команда форума
Sufir, угу. Ты ищешь решение, которое позволит рулить неоткатываемыми операциями :) можно было и самому догадаться, что такого пока нет в природе. Машину времени пока не изобрели...
 

Sufir

Я не волшебник, я только учусь
По моему я достаточно ясно сообщил, что именно я ищу, как минимум два человека поняли. Я не собираюсь "откатывать неоткатываемое".
 

Adelf

Administrator
Команда форума
Ну тема об "атомарности" таких операций. Что подразумевает. Да вощем и неважно... твое решение с задачами конечно не атомарно, но для некоторых нужд - достаточно хорошее.
 

Redjik

Джедай-мастер
еслиб было все так просто, а если RPC изменяет удаленно, и возвращает нечто от чего зависят следующие операции? сам думаю об этом, поэтому и интересуюсь.
двойные проверки и RPC batch запросы

примеры нужны или так понятно?
 

WMix

герр M:)ller
Партнер клуба
мне очень сложно все представляется, те еслиб соеденение было устойчивым, то и удаленному серверу можно сказать откатывайся, но если уровень http, то красивого решения не знаю, лучше пример
 

fixxxer

К.О.
Партнер клуба
В принципе (теоретизируя), можно будет сделать веб-сервис, который будет держать постоянные соединения и активные именованные 2PC транзакции.

Сам так не пробовал делать - обычно не нужно сколько угодно транзакций, хватает двух состояний staging + production и копирования между табличками.
 

WMix

герр M:)ller
Партнер клуба
В принципе (теоретизируя), можно будет сделать веб-сервис, который будет держать постоянные соединения и активные именованные 2PC транзакции.
2PC мне кажется излишеством, те если я понял, прикол несколько в другом, там в дополнении к обычной транзакции есть возможность заранее спросить осущесвима ли она. а про постоянные соеденения и вебсервисы я тогда диаграмку рисовал, ну уж слишком заморочено получается
 

AmdY

Пью пиво
Команда форума
Так как атомарности в разрозненной системе добиться невозможно, я бы решал через систему отката. Для дранзакции генерировал бы UID, который отсылал бы во все системы и на который бы логировалась вся операция, в случае неудач посылал бы инструкции для отката по этому UID. Соответственно, если опереция где-то не прошла, она и не откатилась, а в остальных системах вернулась к прежнему состоянию.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
не откатываемых операций может быть более одной в одном действии. В частности две и более процедуры RPC подряд.
Как сказал Redjik, мы это решили через batch-запросы с MACRO.
Макро-запрос - это передача в запросе нескольких действий и простейшей логики if-then, с использованием в зависимом вызове результата предыдущего.
Мы использовали этот алгоритм для оформления заказа: регистрировали покупателя, потом - заказ, затем адрес доставки, затем создавали счет для оплаты.
Если надо и готов разбираться в этом неделю-другую, могу дать реализацию JSON-RPC2 с макро-запросами.

Еще думал о варианте с задачами. Грубо говоря действие пользователя создеет задачу, а каждая операция представлена подзадачей. И пытаться выполнить задачу, отмечая выполненные операции, пока все выполнены не будут.
Задержка всё же менее критична, чем вообще нарушение целостности.
это никак не решит проблему нарушения целостности, если файл ты уже удалил, а RPC-запрос не выполнился.

Единственный вариант, который я вижу - убрать из алгоритма необратимые действия. Например, вместо удаления файла можно отметить его как удаленный, переместить в корзину, или в изоляции READ COMMITTED поставить в очередь задание на его удаление.
 
Последнее редактирование:

Sufir

Я не волшебник, я только учусь
это никак не решит проблему нарушения целостности, если файл ты уже удалил, а RPC-запрос не выполнился.
Продолжать пытаться выполнить, пока не выполнится (ну, в разумных пределах). Стопроцентной гарантии это так же не дает, но всё-же кол-во невыполненных полностью действий будет гораздо меньше.
убрать из алгоритма необратимые действия. Например, вместо удаления файла можно отметить его как удаленный
Удаление файла можно реализовать как обратимую операцию, но не все операции так можно реализовать. Выполненную процедуру RPC не откатишь, отправлено письмо не вернешь.
Если надо и готов разбираться в этом неделю-другую, могу дать реализацию JSON-RPC2 с макро-запросами.
В любом случае будет интересно и полезно, даже если не применим, буду благодарен.
 

MiksIr

miksir@home:~$
отправлено письмо не вернешь
Вернешь, если письмо отправляется через специальный внутренний сервис, который реальную отправку делает, допустим, через 2 минуты.

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