Как ОБНОВИТЬ элемент, только если кэшированное значение не старше текущего - PullRequest
0 голосов
/ 11 января 2020

У меня есть общая * CRUD система многопользовательского клиентского сервера c java, где каждый пользователь получает все элементы через SELECT, добавляет новые элементы через INSERT, удаляет существующие элементы через DELETE и изменяет существующие элементы через UPDATE.

Все таблицы содержат столбцы date_last_modified TIMESTAMPTZ и user_last_modified INTEGER REFERENCES users(id).

Я хочу предотвратить ситуацию, когда сначала каждый пользователь SELECT s все элементы, а затем несколько пользователей изменить аналогичный элемент, и каждое последующее ОБНОВЛЕНИЕ перезаписывает предыдущие данные.

Я пытаюсь создать запрос UPDATE, который сравнивает значение date_last_modified на клиенте и на сервере, и прерывает запрос, если значения не равны (имеется в виду, что кто-то уже изменил его).

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

Ответы [ 2 ]

0 голосов
/ 11 января 2020

Ваш подход в порядке, но вы можете избежать прерывания запроса (а также избежать запроса метки времени заранее в транзакции для сравнения значений), добавив date_last_modified к

UPDATE ... WHERE ... AND date_last_modified = ?

Если метка времени не соответствует ни одной строке обновляются.

Statement.executeUpdate(...) возвращает количество обновленных строк. Если это 0, вы можете уведомить пользователя о состоянии гонки (и транзакции отката, если необходимо).

Вы также можете добавить столбец serial update_count для этой цели. Тем не менее, timestampz в порядке, если значение изменяется при каждом обновлении.

0 голосов
/ 11 января 2020

Я думаю, что ваш подход хорош, но, возможно, вы сможете реализовать его с помощью триггера перед обновлением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...