Есть ли в Tarantool способ проверить состояние кортежа перед обновлением (optimisti c проверка блокировок / шаблон CAS)? - PullRequest
1 голос
/ 13 июля 2020

Пытаюсь найти информацию о том, как реализовать блокировки optimisti c в БД Tarantool. Этот случай не описан в документации, поэтому я не могу найти способ для такого действия.

Моя цель - найти способ устранить потенциальные конфликты данных для одновременного обновления одних и тех же кортежей от нескольких клиентов (серверов приложений ). При такой загрузке всегда есть задержка между чтением кортежа и его обновлением - так что есть место для условий гонки. Я стараюсь избегать пессимистичных c блокировок в распределенной системе - для такой блокировки нам нужен дополнительный компонент - и любое добавление нового компонента должно выполняться с учетом многих соображений.

Ответы [ 2 ]

1 голос
/ 16 июля 2020

Это будет хранимая процедура, подобная следующей (код упрощен):

function update_cas(key, tuple, version)
   local old = space:get(key)
   if old.version ~= version then error('Oops!') end
   tuple[VERSION_FIELD_NUMBER] = version + 1
   space:replace(tuple)
end

Надеюсь, это дает вам идею.

0 голосов
/ 15 июля 2020

Если я правильно понимаю ваш вопрос, я могу предложить вам следующую схему.

Добавьте новое поле «версия» или «отметка времени» в ваш кортеж. И проверьте его перед выполнением операции обновления.

Пример: у меня есть схема {id, value, version} и начальный кортеж {1, 0, 0}.

Получен первый запрос запроса кортеж {1, 1, 0} и пытается выполнить операцию обновления {{'+', 'value', 1}} и «только если версия == 0». Затем вы go в хранилище, чтобы сохранить результат. Перед сохранением вы получаете исходный кортеж и проверяете, что версия равна «0», а затем сохраняете кортеж. Теперь вы обновили кортеж {1, 1, 1}.

Представьте, что у вас есть второй запрос, связанный с обновлением того же кортежа с операцией {{'+', 'value', 2}} и снова с "только если версия == 0". Вы пытаетесь сохранить его, но когда вы получаете кортеж с id = 1, вы получаете {1, 1, 1}. Это не удовлетворяет условию only_if_version == 0 (поскольку текущая версия кортежа равна 1). В этом случае вы возвращаете своему пользователю ошибку.

...