Я не уверен в правильном дизайне подхода.Оптимистическая блокировка и повторная попытка
Мы используем оптимистичную блокировку с использованием long
инкрементной версии, размещенной на каждом объекте. Каждое обновление такого объекта выполняется с помощью алгоритма сравнения и свопинга, который просто преуспевает или выходит из строя в зависимости от того, является ли какое-то другое средство обновления клиента тем временем или нет. Классическая оптимистическая блокировка, например. спящий режим.
Нам также необходимо принять повторный подход. Мы используем хранилище на основе http
(etcd), и может случиться, что некоторый запрос на обновление просто отключен.
И вот в чем проблема. Как сочетать оптимистичную блокировку и повторную попытку. Вот конкретная проблема, с которой я сталкиваюсь.
Позвольте сказать, что у меня есть объект, имеющий version=1
, и я пытаюсь его обновить. Следующая версия, очевидно, 2
. Мой клиент, чем выполняет условное обновление. Он успешно выполняется только в том случае, если версия с сохранением - 1
, и она автоматически обновляется до version=2
. Все идет нормально.
Теперь скажем, что ответ на запрос обновления не поступает. Невозможно сказать, удалось ли это или нет в данный момент. Единственное, что я могу сделать сейчас, это: повторите попытку обновления. В объекте памяти все еще содержится version=1
, намеревающийся обновить значение до 2
.
Настоящая проблема возникает сейчас. Что делать, если второе обновление не выполняется, потому что версия с сохранением - 2
, а не 1
?
Существует две возможные причины:
- первый запрос действительно вызвало обновление - операция прошла успешно, но ответ был потерян или мой клиент тайм-аут, что угодно. Он просто не пришел, но он прошел
- другой клиент выполнил обновление одновременно на фоне
Сейчас я не могу сказать, что это правда. Мой клиент обновил объект или какой-либо другой клиент? Произошла или не прошла операция?
Текущий подход, который мы используем только , сравнивает постоянный объект и объект в основной памяти. Либо как java равно, либо json-контент. Если они равны, методы обновления объявляются успешными. Я не доволен алгоритмом, поскольку он не дешев и не разумен для меня.
Другой возможный подход заключается в том, чтобы не использовать long
, но вместо этого timestamp
. Каждый клиент генерирует собственную метку времени в рамках операции обновления в смысле, что потенциальный одновременный клиент будет генерировать другие с высокой вероятностью. Проблема для меня - это вероятность, особенно когда два параллельных обновления будут поступать с одной машины.
Есть ли другое решение?