#sql-update #multi-user #optimistic-concurrency #pessimistic-locking
#sql-обновление #многопользовательский #оптимистичный-параллелизм #пессимистичный-блокировка
Вопрос:
Я прочитал статью.
В статье описывается следующее решение ситуаций, когда многие пользователи могут выполнять запись в одну и ту же БД.
Вам, как пользователю, необходимо:
- Извлеките строку и последнее изменение
dateTime
строки. - Выполните необходимые вычисления, но пока ничего не записывайте в БД.
- После вычислений, непосредственно перед тем, как вы захотите записать результат в БД, снова извлеките последнее изменение
dateTime
той же строки. - Сравните дату и время # 1 с
dateTime
# 2. Если они равны — все в порядке, зафиксируйте и запишите текущее время как дату последнего изменения времени строки. else — здесь был другой пользователь — Откат.
Этот процесс кажется логичным, НО я вижу в нем следующую дыру:
В # 3 пользователь извлекает последнее изменение dateTime
строки, но что, если между чтением этого dateTime
(в # 3) и временем записи в # 4 другой пользователь вводит, записывает свои данные и выходит? Первый пользователь никогда не узнает об этом, и это переопределит данные второго пользователя.
Разве это невозможно?
Ответ №1:
У алгоритма, который вы описываете, действительно есть возможность пропустить одновременное обновление между шагами # 3 и # 4.
В части, посвященной тестированию на наличие нарушений оптимистичного параллелизма, говорится:
При попытке обновления значение временной метки в базе данных сравнивается с исходным значением временной метки, содержащимся в измененной строке. Если они совпадают, выполняется обновление, и столбец метки времени обновляется текущим временем, чтобы отразить обновление. Если они не совпадают, произошло нарушение оптимистичного параллелизма.
Хотя это и не упоминается явно, идея заключается в том, чтобы этап сравнения и обновления выполнялся атомарно на сервере. Это можно сделать с помощью инструкции UPDATE, содержащей предложение WHERE, включающее временную метку и ее исходное значение. Аналогично примеру, упомянутому в статье, где все исходные значения столбцов в строке по-прежнему соответствуют значениям, найденным в базе данных.