Рассмотрим корзину пользователя и оформление заказа: клиент может выполнить действие addItemToCart, которое будет обрабатываться основным экземпляром БД. Однако действие getUserCartItems может быть выполнено для реплики чтения, и оно может еще не содержать результат первого действия из-за задержки реплики. Даже если мы попытаемся минимизировать это отставание, все же возможно поразить это дело, поэтому мне интересно, какие решения вы пробовали в производстве?
В соответствии с @Henrik ответ, у нас есть 3 варианта:
1. Wait at user till consistent.
Это означает, что нам нужно выполнить опрос (обычный или длительный опрос) на клиенте и подождать, пока реплика получит обновление. Тем не менее, я предполагаю, что задержка реплики не должна превышать 1-5 секунд. Кроме того, чем меньше задержка реплики, тем ниже будет производительность.
2. Ensure consistency through 2PC.
Если я правильно понял, нам нужно объединить оба addItemToCart insert и getUserCartItems select в одну агрегатную операцию на бэкэнде и вернуть getUserCartItems в качестве ответа addItemToCart. Тем не менее, следующий запрос может все еще не получить обновленную информацию из-за задержки … Да, он возвращает немедленное подтверждение об успешной работе, и приложение может продолжаться, однако для оформления заказа требуются элементы корзины пользователя, чтобы правильно показать цену, поэтому мы не фиксируем проблема в любом случае.
3. Fool the client.
Приложение сохраняет / кэширует все успешно отправленные данные и использует их для показа. Да, это решение, но оно определенно требует реализации дополнительной бизнес-логики:
Perform getUserCartItems request;
if (getUserCartItems returned success)
Store addItemToCart in local storage;
else
Show error and retry;
Perform getUserCartItems request;
if (getUserCartItems contains addItemToCart ID)
Update local storage / cache and proceed with it.
else
Use existing data from local storage;
Как вы справляетесь с возможным несоответствием?
Правильный ответ — НЕ отправлять запросы SELECT на ведомое устройство чтения, если данные должны быть немедленно доступны.
Вы должны структурировать свое приложение так, чтобы все запросы в режиме реального времени попадали на ваш мастер, а все остальные запросы — на одного из ваших ведомых читателей.
В тех случаях, когда вам не нужны результаты в реальном времени, вы можете достаточно хорошо обмануть пользователя, используя что-то вроде AJAX-запросов или веб-сокетов (веб-сокеты сделают ваше приложение более дружественным к ресурсам, так как вы не будете забивать свои серверы бэкэнда). с несколькими AJAX-запросами).
Других решений пока нет …