gifts2017

Блокировка данных при выполнении запроса в транзакции

Опубликовал Дмитрий Константинов (Agamest) в раздел Программирование - Теория программирования

При подготовке к аттестации "1С:Эксперт по технологическим вопросам" возник ряд вопросов по блокировке объектов при выполнении запроса в транзакции в автоматическом режиме управления блокировкой данных. В частности возник вопрос, а правда ли что при запросе в транзакции блокируются не только возвращаемые данные, но возможно, и вся таблица если идет ее просмотр. Кому интересны мои эксперименты прошу под кат.

Для проведения экспериментов создаем в базе справочник "Товары" с реквизитами "РеквизитИндексированный" по которому создан индекс и "РеквизитНеИндексированный" по которому соответственно индекса нет.

 

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

     

Наименование

Реквизит не индексирован

Реквизит индексированный

 

Кресло мягкое

2

2

 

Стул 999

3

1

 

Товар 0

2

2

 

Товар 0

2

1

 

Товар 00

3

2

 

Товар 00

3

1

 

Товар 10 (изменено)

1

2

 

Товар 102

0

0

 

Товар 103

0

0

 

Товар 104

0

0

 

 

Далее запускаем на выполнение данный код, поставив точку останова на строке ЗафиксироватьТранзакцию()

Запрос выполняется по следующему плану

В паралельной сессии начнем эксперементировать, для начала проверим блокируется ли вся таблица. Для этого открываем элемент у которого оба реквизита не равны 2, например "Стул 999", пытаемся изменить его в различных вариантах, ошибок блокировки объекта нет. Значит таблица не блокируется полностью.

Далее, пытаемся изменить элемент у которого РеквизитИндексированный равен 2, РеквизитНеИндексированный НЕ равен 2, т.е. элемент по которому был поиск по индексу, но не было поиска ключа по кластерному индексу, например "Товар 10 (изменено)". Система дает нам изменить любой реквизит кроме того, по которому осуществлялся поиск в индексе. Можно изменить наименование, код, все кроме "РеквизитИндексированный"

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

В итоге получилась вот такая таблица:

Вид объекта

Оператор плана запроса

Блокировка данных с граничными строками?*

Блокировка строки или всей таблицы?

Блокируется строка либо поле?

Регистр сведений

Index Seek

Да

Строка

Строка

Регистр сведений

Clustered Index Seek

Да

Строка

Строка

Регистр сведений

Index Scan

 

Таблица

Строка

Регистр сведений

Clustered Index Scan

 

Таблица

Строка

Справочник

Index Seek

Нет

Строка

Поле

Справочник

Clustered Index Seek

Нет

Строка

Строка

Справочник

Index Scan

Нет

Строка

Поле

Справочник

Clustered Index Scan

Нет

Строка

Строка

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


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

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Антон Стеклов (asved.ru) 31.12.14 11:08
Что-то я не понял, о чем Вы хотите рассказать. Блокируются данные в той таблице, из которой были прочитаны. Т.е. если происходит clustered index seek - блокируются строки таблицы кластерного индекса, т.е. по сути своей строки основной таблицы. Если делается seek по некластерному индексу - блокируются его строки, соответственно, когда мы изменяем индексированный реквизит, мы пытаемся обновить индекс по этому реквизиту, а он блокирован. Блокировки же поля строки вообще не бывает. На основании чего в таблице указаны накладываемые при различных scan блокировки - вообще не понятно, нет у вас сканов в плане запроса.

Кстати, а чем table scan отличается от clustered index scan, Вы разобрались?
Evil Beaver; alexscamp; Redokov; zzz14; +4 Ответить 1
2. Babuin 31.12.14 11:30
да статья невнятная, плюс не указана структура индекса, плюс не показано какие блокировки и как накладываются и выводы неверные как уже сказали нет блокировки поля, есть блокировки строк или страниц, ключей диапазонов и таблиц.
3. Константин Гаевский (zzz14) 31.12.14 12:30
> блокируется только нижняя граничная запись.
Лучше об этом прочитать в документации.
MSDN: Число установленных блокировок Range равно n+1, где n — это число строк, удовлетворяющих запросу. Подробнее.

Вы участник курса по опимизации 1С?
4. Алексей Роза (DoctorRoza) 31.12.14 12:34
При подготовке к аттестации "1С:Эксперт по технологическим вопросам" возник ряд вопросов по блокировке объектов при выполнении запроса в транзакции в автоматическом режиме управления блокировкой данных.


Вам нужно еще раз внимательно пересмотреть курс. Андрей Бурмистров четко говорит, что в автоматическом режиме блокировок всегда блокируется вся таблица, в управляемом - только нужные записи.
5. Алексей Роза (DoctorRoza) 31.12.14 12:36
(3) zzz14, однозначно, да! Этот курс хорош, но его еще нужно переосмыслить!
6. Babuin 31.12.14 12:56
(4) DoctorRoza, это не так. Гранулярность блокировок в MS SQL не зависит от режима управления блокировок в 1С.
7. Константин Гаевский (zzz14) 31.12.14 14:58
(4) DoctorRoza,

Андрей Бурмистров этого не говорил.
8. Антон Стеклов (asved.ru) 01.01.15 16:27
(4) DoctorRoza, вероятно, Андрей говорит про Postgre или файловую БД. Ибо табличная блокировка в MSSQL - однозначно объект для разбирательства даже в режиме автоблокировок.

(3) zzz14, по большому счету это уже непринципиально, т.к. блокировка области в любом случае скорее всего избыточна. И стало практически неважным с появлением режима управляемых блокировок, когда транзакция осуществляется в read_committed. Безусловно, можно говорить о том, что блокировка существует, пока в транзакции выполняется долгий запрос, но долгий запрос, да еще и с избыточными блокировками - сам по себе объект для разбирательства.
9. Игорь Нешик (ineshyk) 03.01.15 00:59
(4) DoctorRoza, да бред.
Это не верно.
Автоматический режим отличается только уровнем изоляции.
Грянулярность тут ни при чем.
10. Дмитрий Константинов (Agamest) 03.01.15 18:26
(1) asved.ru,

Что-то я не понял, о чем Вы хотите рассказать. Блокируются данные в той таблице, из которой были прочитаны. Т.е. если происходит clustered index seek - блокируются строки таблицы кластерного индекса, т.е. по сути своей строки основной таблицы. Если делается seek по некластерному индексу - блокируются его строки, соответственно, когда мы изменяем индексированный реквизит, мы пытаемся обновить индекс по этому реквизиту, а он блокирован.

Примерно вот это я и хотел сказать, в зависимости от того что именно читается и как, может блокироваться либо вся таблица, либо "строка"(если смотреть на метаданные 1С) таблицы, либо "поле" (опять же если смотреть на метаданные 1С) таблицы

На основании чего в таблице указаны накладываемые при различных scan блокировки - вообще не понятно, нет у вас сканов в плане запроса.

Я не стал приводить все этапы тестирования, например для регистров, это итоговая таблица.

Кстати, а чем table scan отличается от clustered index scan, Вы разобрались?

В одном случае идет просмотр кластерного индекса, в другом таблицы? Нет?
11. Дмитрий Константинов (Agamest) 03.01.15 18:33
(3) zzz14,
Спасибо за ссылку, прочту. Да, вы правы, прошел недавно этот курс.
12. Антон Стеклов (asved.ru) 09.01.15 16:09
(10) Agamest,
либо "поле" (опять же если смотреть на метаданные 1С) таблицы

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

В одном случае идет просмотр кластерного индекса, в другом таблицы? Нет?

Логично. Но возникает вопрос: а кластерный индекс - это таблица или нет? И что такое просмотр? Не забываем про существование оператора seek ... where.

Да, вы правы, прошел недавно этот курс

Благодарю, сделал определенные выводы.
13. Дмитрий Константинов (Agamest) 09.01.15 19:36
(12) asved.ru,

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

Спасибо за поправку, буду знать что на экзамене нельзя абстрагироваться от понятий БД

Логично. Но возникает вопрос: а кластерный индекс - это таблица или нет? И что такое просмотр? Не забываем про существование оператора seek ... where.

Кластерный индекс на уровне листьев хранит данные, таблица включена в индекс. Соответственно просмотр кластерного индекса это просмотр его листьев. При seek where мы переходим с помощью seek на определенный уровень дерева, после чего просматриваем его листья и сравниваем с where. Я не прав?
Seneka7608; +1 Ответить 1
14. Антон Стеклов (asved.ru) 10.01.15 20:15
(13) Agamest, абстрагироваться от понятий БД можно и нужно, если речь идет о процессе, протекающем выше уровня БД, к примеру, об управляемых блокировках. Но - при разборе управляемых блокировок и ожиданий на них нельзя забывать и о том, что они в любом случае сопровождаются блокировками СУБД согласно уровню изоляции транзакции.

Вот есть у нас непериодический регистр сведений, три измерения, несколько неиндексированных ресурсов. В запросе накладывается условие
1) на второе измерение
2) На первое, третье измерения и ресурс

Поставьте эксперимент, какими операторами в данных случаях будет выполняться чтение. Рассмотрите случаи с небольшим и значительным количеством записей. Ну и с различной селективностью по заданному условию.
Seneka7608; +1 Ответить
15. Сергей Носков (Sergey.Noskov) 19.01.15 13:45
Блокировку таблицы справочника целиком можно наблюдать при эскалации блокировок.
Для этого достаточно, что бы в операторе "Поиск ключа" (Key Lookup) было обработано более 5000 строк индекса (параметр настраиваемый). Думаю именно этот эффект вы на регистрах сведений и наблюдали.
16. Антон Стеклов (asved.ru) 27.01.15 20:33
(15) Sergey.Noskov, вы все еще не отключаете эскалацию по количеству? Тогда мы идем к вам! ;)
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа