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

Я понимаю разницу между оптимистической и пессимистической блокировкой*. Теперь может кто-нибудь объяснить мне, когда я буду использовать любой из них в целом?

и меняется ли ответ на этот вопрос в зависимости от того, использую ли я хранимую процедуру для выполнения запроса?

*но просто для проверки, оптимистический означает "не блокировать таблицу во время чтения" и пессимистический означает "заблокировать таблицу во время чтения."

8 ответов


Оптимистическая Блокировка - это стратегия, в которой Вы читаете запись, принимаете к сведению номер версии (другие методы для этого включают даты, метки времени или контрольные суммы/хэши) и проверяете, что версия не изменилась, прежде чем записывать запись обратно. Когда вы пишете запись назад, вы фильтруете обновление версии, чтобы убедиться, что оно атомарное. (т. е. не обновлялся между проверкой версии и записью на диск) и обновлением версии в одном удар.

Если запись загрязнена (т. е. отличается от вашей версии), вы прерываете транзакцию, и пользователь может снова запустить ее.

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

Пессимистической Блокировки - это когда вы блокируете запись для исключительного использования, пока не закончите с ней. Он имеет гораздо лучшую целостность, чем оптимистическая блокировка, но требует, чтобы Вы были осторожны с дизайном приложения, чтобы избежать взаимоблокировок. Чтобы использовать пессимистическую блокировку, вам нужно либо прямое подключение к базе данных (как это обычно бывает в клиент-сервер уровня приложения) или внешний идентификатор транзакции, который можно использовать независимо от соединения.

в последнем случае вы открываете транзакцию с TxID, а затем повторно подключаетесь с помощью этого идентификатора. СУБД поддерживает блокировки и позволяет выбрать сеанс резервного копирования через TxID. Вот как распределенные транзакции используют двухфазные протоколы фиксации (например,XA или транзакции com+) работы.


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

пессимистическая блокировка используется, когда ожидается столкновение. Транзакции, которые нарушают синхронизацию, просто блокируются.

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


оптимист предполагает, что ничего не изменится, пока вы его читаете.

пессимистический предполагает, что что-то будет и поэтому блокирует его.

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

большинство веб-приложений в порядке с грязными считываниями - в редких случаях данные точно не подсчитывают следующую перезагрузку делает.

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

О, и Microsoft SQL server по умолчанию блокирует страницы-в основном строку, которую Вы читаете, и несколько с каждой стороны. Блокировка строк более точная, но гораздо медленнее. Часто стоит настроить транзакции на чтение-фиксацию или без блокировки, чтобы избежать тупиков, пока чтение.


в дополнение к тому, что уже было сказано, следует сказать, что оптимистическая блокировка имеет тенденцию улучшать параллелизм за счет предсказуемости. Пессимистическая блокировка имеет тенденцию уменьшать параллелизм, но более предсказуема.

вы платите свои деньги и т. д.


Я бы подумал еще об одном случае, когда пессимистическая блокировка была бы лучшим выбором.

для оптимистической блокировки каждый участник модификации данных должен согласиться с использованием такого рода блокировки. Но если кто-то изменяет данные, не заботясь о столбце version, это испортит всю идею оптимистической блокировки.


есть в основном два самых популярных ответа. The первый в основном говорит

Optimistic нуждается в трехуровневой архитектуре, где вы не обязательно поддерживаете соединение с базой данных для своего сеанса, тогда как пессимистическая блокировка-это когда вы блокируете запись для исключительного использования, пока не закончите с ней. Он имеет гораздо лучшую целостность, чем оптимистическая блокировка, вам нужно либо прямое соединение с база данных.

другой ответ

оптимистичный (управление версиями) быстрее из-за отсутствия блокировки, но (пессимистическая) блокировка работает лучше, когда конкуренция высока, и лучше предотвратить работу, а не отказаться от нее и начать все сначала.

или

оптимистичная блокировка работает лучше всего, когда у вас есть редкие столкновения

С на этой странице.

Я создал свой ответ, чтобы объяснить, как "сохранить соединение" связано с "низкими столкновениями".

чтобы понять, какая стратегия лучше для вас, подумайте не о транзакциях в секунду, а о продолжительности одной транзакции. Обычно вы открываете trasnaction, выполняете операцию и закрываете транзакцию. Это короткая, классическая транзакция, которую Анси имел в виду и хорошо, чтобы уйти с блокировкой. Но, как вы реализуете систему бронирования билетов, где много клиенты зарезервировать одинаковых номеров/мест одновременно?

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

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

в этом оптимистичном подходе вы должны записать все данные что Вы читаете (как в мой повторил читать) и приходите к точке фиксации с вашей версией данных (я хочу купить акции по цене, указанной в этой котировке, а не по текущей цене). На этом этапе создается транзакция ANSI, которая блокирует БД, проверяет, не изменилось ли что-либо, и фиксирует/прерывает вашу операцию. ИМО, это эффективная эмуляция MVCC, который также связан с Optimistic CC, а также предполагает, что ваша транзакция перезапускается в случае прерывания, что вы сделаете новое бронирование. Транзакция здесь включает человеческие решения пользователя.

Я далек от понимания того, как реализовать MVCC вручную, но я думаю, что длительные транзакции с возможностью перезапуска являются ключом к пониманию предмета. Поправьте меня, если я где-нибудь ошибаюсь. Мой ответ был мотивирован это Алексей Кузнецов глава.


в большинстве случаев оптимистичная блокировка более эффективна и обеспечивает более высокую производительность. При выборе между пессимистической и оптимистической блокировкой учитывайте следующее:

  • пессимистическая блокировка полезна, если есть много обновлений и относительно высокая вероятность того, что пользователи попытаются обновить данные одновременно время. Например, если каждая операция может обновить большое количество записи за один раз (банк может добавить процентный доход к каждому счет в конце каждого месяц), и два приложения запущены такие операции в то же время будут иметь конфликты.

  • пессимистическая блокировка также более уместна в приложениях, содержащих небольшие таблицы, которые часто обновляются. В случае с этими так называемыми "горячими точками" конфликты настолько вероятны, что оптимистическая блокировка тратит усилия на откат конфликтующих транзакций.

  • Оптимистическая блокировка полезна, если возможность конфликтов очень низкий-есть много записей, но относительно мало пользователей, или очень мало обновлений и в основном операций типа чтения.


одним из вариантов использования оптимистической блокировки является использование вашим приложением базы данных, чтобы позволить одному из ваших потоков / хостов "претендовать" на задачу. Это техника, которая мне пригодилась на регулярной основе.

лучший пример, который я могу придумать, - это очередь задач, реализованная с использованием базы данных, с несколькими потоками, претендующими на задачи одновременно. Если задача имеет статус "доступно", "заявлено", "завершено", запрос БД может сказать что-то вроде "Set status= "Claimed", где status= 'доступно'. Если несколько потоков попытаются изменить состояние таким образом, все, кроме первого потока, завершатся ошибкой из-за грязных данных.

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