Оптимистическая и пессимистическая блокировка - PullRequest
454 голосов
/ 24 сентября 2008

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

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

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

Ответы [ 8 ]

675 голосов
/ 24 сентября 2008

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

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

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

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

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

145 голосов
/ 24 сентября 2008

Оптимистическая блокировка используется, когда вы не ожидаете много столкновений. Обычная операция обходится дешевле, но если коллизия ДЕЙСТВИТЕЛЬНО произойдет, вы заплатите более высокую цену за ее разрешение при отмене транзакции.

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

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

62 голосов
/ 24 сентября 2008

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

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

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

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

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

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

39 голосов
/ 24 сентября 2008

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

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

17 голосов
/ 04 апреля 2013

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

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

9 голосов
/ 08 декабря 2016

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

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

Другой ответ

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

или

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

Как написано на этой странице.

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

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

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

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

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

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

7 голосов
/ 16 июля 2017

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

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

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

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

2 голосов
/ 27 марта 2017

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

Лучший пример, который я могу придумать, - это очередь задач, реализованная с использованием базы данных, когда несколько потоков одновременно выполняют задачи. Если задача имеет статус «Доступно», «Заявлено», «Завершено», запрос БД может сказать что-то вроде «Установить статус =« Заявлено », где статус =« Доступно ». Если несколько потоков пытаются изменить статус таким способом, все, кроме первого потока, потерпят неудачу из-за грязных данных.

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

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