elglin: (Default)
[personal profile] elglin
В своем текущем поделии как разумный человек я вынес всю работу с базой в отдельный модуль. И фоновые задачи у меня тоже живут в отдельном от вебинтерфейса модуле.
И тут возникла проблема. Как часто бывает, некоторую часть реализации бизнес-логики надо делать в контексте одной SQL-транзакции (SELECT FOR UPDATE + UPDATE). И тут получается, что либо надо затаскивать транзакцию в логику (до свидания, инкапсуляция БД), либо совать сложную логику в контекст работы с базой (нечего ей там делать). И кольцевые импорты опять же.
Но тут, раз все равно работаю с асинхронщиной, решение пришло практически само. При вызове функции работы с БД ей в т.ч. передается коллбэк родом из модуля фоновых задач. Инкапсуляция на месте, кольцевых импортов нет, и пастуху вечная память.

Да, чтобы два раза не вставать. Как только у вас вместо долгого и задумчивого 201 Created появляется быстрый и резкий 202 Accepted, у вас сразу же возникают проблемы с внутренней консистентностью, которую надо решать. Грубо говоря, из двух действий: "сделать что-то" и "записать, что сделал что-то" вы всегда сначала делаете одно, а потом другое, и вот если панночка померла аккурат между ними, то у вас неконсистентность. В сколь-нибудь распределенной системе, в которой есть сколь-нибудь долгие процессы, панночка будет регулярно помирать именно в этой позе.

(no subject)

Date: 2020-04-04 04:23 pm (UTC)
beldmit: (Программизм)
From: [personal profile] beldmit
У меня в последнем проекте каждая операция с точки зрения бизнеса - одна транзакция. В начале функции проверяем, что мы внутри таковой. Да, SELECT FOR UPDATE внутри этого модуля там, где нужен.

С внутренней консистентностью проблема возникает, если надо как-то провзаимодействовать с внешним миром (письмо отправить или к сервису стукнуться). Да, неконсистентность тут запросто вылезет, ну а дальше вопрос про частоту отвала того сервиса. Может, проще ручками устранить раз в неделю, что мы запрос послали, сервер его отработал, а коннект оторвался. Ну а пользователь всяко перетопчется, если получит 2 письма вместо одного.

(no subject)

Date: 2020-04-05 11:14 am (UTC)
beldmit: (Default)
From: [personal profile] beldmit
Ну да, к этому все и приходят :)

(no subject)

Date: 2020-04-04 06:57 pm (UTC)
brmail: (Default)
From: [personal profile] brmail
ну транзакции-то в самом деле вовсю реализованы, со стороны сервера ведь поддерживаются, вот и пусть сервер сам с транзакциями разбирается, надо только обеспечить выполнение внутри sql транзакций. Ну типа ADO.NET прикрутить или что там есть для сервера. Если уж совсем никак озадачить этим ваш сервис, то может просто загонять в отдельную табличку построчно все действия для транзакции, и после завершения наполнения - выполнять разом.
Так оно получится как dynamic sql, что геморойно, но вполне реализуемо

(no subject)

Date: 2020-04-05 05:03 pm (UTC)
brmail: (Default)
From: [personal profile] brmail
ну дело то обычное, как на елку залезть и ничего не ободрать. Если есть необходимость именно такого подхода, то либо лок на рекордсет на все время транзакции, либо менять подход
Page generated Jun. 23rd, 2025 06:45 pm
Powered by Dreamwidth Studios