Статьи

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

Вступление

Все мы знаем об уровне изоляции MS SQL Server. Но есть определенная путаница, связанная с техникой оптимистической блокировки. Эта статья предназначена для продвинутого разработчика SQL, чтобы узнать и понять систему Optimistic Locking. Если вы новичок в уровне изоляции, пожалуйста, прочитайте мою предыдущую статью под названием Уровень изоляции MS SQL Server . Надеюсь, это будет знающим и полезным. 

Как найти текущий уровень изоляции

Чтобы найти текущий уровень изоляции в вашей базе данных, используйте этот оператор SQL :

 SELECT CASE transaction_isolation_level
                  WHEN 0 THEN 'Unspecified'
                  WHEN 1 THEN 'ReadUncommitted'
                  WHEN 2 THEN 'ReadCommitted'
                  WHEN 3 THEN 'Repeatable'
                  WHEN 4 THEN 'Serializable'
                  WHEN 5 THEN 'Snapshot' END AS TRANSACTION_ISOLATION_LEVEL
FROM  sys.dm_exec_sessions
WHERE session_id = @@SPID;

Проблема с блокировкой

Поскольку мы все знаем, что для чтения данных из базы данных (SELECT…) устанавливается Shared Lock, и когда мы выполняем операцию DML или записываем что-то в базу данных, мы использовали Exclusive Lock. И общая, и эксклюзивная блокировки не совместимы друг с другом, что означает, что когда мы пишем что-то, что мы не можем прочитать, или когда мы читаем, мы не можем писать.

Конечно же, мы можем выполнить подсказку «Грязное чтение по уровню изоляции ЧИТАТЬ НЕКОММИТИРОВАННО» или « С (NOLOCK)» . Но это совсем не рекомендуется, и все разработчики знают, почему?

Так что решения

Начиная с MS SQL Server 2005, Microsoft предоставляет нам два типа Оптимистичной блокировки, чтобы получить это решение.

1.   SNAPSHOT

2.   ПРОЧИТАЙТЕ КОММЕНТАРИЙ

Оба уровня изоляции используют технику версии строки и используют базу данных TempDB.

Преимущества, которые мы получаем от этого уровня изоляции: Чтение не блокирует запись, а запись не блокирует чтение в случае среды OLTP.

Реализация оптимистической блокировки

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

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

Seep-1 [Наша производственная среда может обрабатывать эту нагрузку]                                           

Когда мы изменяем уровень изоляции на SNAPSHOT, MS SQL Server ожидает завершения транзакции и запускает контроль версий для модификации данных. Для этого он начинает использовать дополнительные 14 байтов на строку в таблице.

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

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

Мы должны контролировать нашу систему для этого. Для этого можно использовать счетчик производительности SQL-сервера.

Шаг 2 [Мы должны выбрать]

Мы должны тщательно выбирать между Snapshot и Read Committed Snapshot.

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

 ALTER DATABASE IsolationTests 
SET ALLOW_SNAPSHOT_ISOLATION ON

Затем мы должны использовать уровень изоляции Snapshot для транзакций следующим образом:

 SET TRANSACTION ISOLATION LEVEL SNAPSHOT
BEGIN TRAN
.....
.....

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

С другой стороны, READ COMMITED SNAPSHOT принимает только настройки уровня базы данных, подобные этой.

 ALTER DATABASE IsolationTests 
SET READ_COMMITTED_SNAPSHOT ON

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

Надеюсь, вам понравится.