Поделиться через


Оптимистическая блокировка

Оптимистическая параллелизм получает свое имя от оптимистического предположения о том, что столкновения между транзакциями редко возникают; конфликт возникает при обновлении другой транзакции или удалении строки данных между временем чтения текущей транзакцией и временем обновления или удаления. Это противоположность пессимистичного параллелизма или блокировки, в которой разработчик приложений считает, что такие столкновения являются обычными.

В оптимистической параллелизме строка остается разблокированной до тех пор, пока не придет время обновить или удалить его. На этом этапе строка перечитается и проверка, чтобы узнать, была ли она изменена с момента последнего чтения. Если строка изменилась, обновление или удаление завершается ошибкой и необходимо повторить попытку.

Чтобы определить, была ли изменена строка, новая версия проверка для кэшированных версий строки. Это проверка можно использовать в зависимости от версии строки, например столбца метки времени в SQL Server или значений каждого столбца в строке. Многие СУБД не поддерживают версии строк.

Оптимистическая параллелизм может быть реализована источником данных или приложением. В любом случае приложение должно использовать низкий уровень изоляции транзакций, например Read Committed; использование более высокого уровня отрицает увеличение параллелизма, полученного с помощью оптимистического параллелизма.

Если оптимистическое параллелизм реализуется источником данных, приложение задает атрибут оператора SQL_ATTR_CONCURRENCY SQL_CONCUR_ROWVER или SQL_CONCUR_VALUES. Чтобы обновить или удалить строку, она выполняет позиционированную инструкцию обновления или удаления или вызывает SQLSetPos так же, как и с пессимистичным параллелизмом; драйвер или источник данных возвращает SQLSTATE 01001 (конфликт операции курсора), если обновление или удаление завершается сбоем из-за столкновения.

Если приложение реализует оптимистическое параллелизм, оно задает атрибут оператора SQL_ATTR_CONCURRENCY для чтения строки SQL_CONCUR_READ_ONLY. Если он сравнивает версии строк и не знает столбец версии строки, он вызывает SQLSpecialColumns с параметром SQL_ROWVER, чтобы определить имя этого столбца.

Приложение обновляет или удаляет строку, увеличив параллелизм, чтобы SQL_CONCUR_LOCK (для получения доступа к строке) и выполнения инструкции UPDATE или DELETE с предложением WHERE, указывающего версию или значения строки, когда приложение считывает его. Если строка изменилась с тех пор, инструкция завершится ошибкой. Если предложение WHERE не однозначно определяет строку, инструкция также может обновлять или удалять другие строки; версии строк всегда однозначно определяют строки, но значения строк однозначно определяют строки, только если они включают первичный ключ.