который юзер может вызвать несколько раз подряд - создание подписки. но пока данные не записались в базу, api не может знать что у него она есть. по этому возможно что если два запроса идут с маленькой задержкой, то пописка создасться два раза - так как api ждет ответ от stripe. как это можно решить без очередей?
Записываешь данные об ожидании подписки в условный редис и проверяешь Подписка записалась в базу - удалил из редиса
тут минус в том что если что то пойдет не так, то этот кеш надо будет чистить потом или с ttl ставить. короче может получитсья что и подписки нет и создать ее еще раз нельзя
У тебя получается, что транзакция в базу данных не закрывается, пока не получен ответ от stripe?
НУ всё ранво, обхясни как оркестровка происходит между сохранненим в бд и отправкой запроса в stripe
в двух словах если получилось списать за подписку, то обновляется данные подписки в user.subscription проперти
Тебе нужны локи. В монге вроде только optimistic locking можно сделать
Получается, сначала идет запрос в страйп, и если он успешный, то запрос в бд для обновления данных подписки в user.subscription проперти?
да в этом и проблема что если ответ будет долгий от страйпа или два раза очень рядом пройдут два запроса, то не успеет обновьтся состояние подписки.
Ну да. По version полю. По монге много туториалов на эту тему должно быть. Но может это и не то, что тебе надо. Я чет не особо читал, что ты еще писал
Мне кажется проблема в том, что ты хочешь сделать транзакционную консистентность между запросом к стороннему сервису и в свою бд. Это тоже можно сделать, но самому реализовывать транзакционную консистентности мне кажется проблемно. А что если отказаться от транзакций и сделать eventual consistency? Что-то типа - создать инвойс, показать юзеру что он в процессе оплаты. А когда оплатится, то перевести в статус оплачено и активировать подписку
если оч коротко: updateSubscription() { // 1. call stripe to create subscription // 2. update user.subscription }
А ты когда к страйпу 2 раза обращаешься, два раза у пользователя деньги снимаешь?
это конечно идеальный вариант, но это не с нуля система пишется, кое что изменять нельзя, иначе надо будет обновлять UI которому оч много лет. короче пока наверно самое эффективное это lock для документа. типа надо сразу включать весь функционал если оплата прошла успешно, а если все это реализовывать сейчас то это надолго.
А вот еще вопрос Ты сделал запрос в stripe, но связь оборвалась. Ты это как будешь разруливать? Ведь нет гарантии того, что оплата не прошла
После каждого запроса слать проверочный?
А бац и еще раз оборвалась связь. Не смог проверить
Ну и ещё момент. Может быть так, что проверочный запрос вернул, что деньги не списались из-за того, что первый (оборванный) запрос ещё не завершился В итоге клиент не получает то, за что он заплатил
Интересно, в таком случае мало что можно сделать.
Обсуждают сегодня