Для проведения экспериментов создаем в базе справочник «Товары» с реквизитами «РеквизитИндексированный» по которому создан индекс и «РеквизитНеИндексированный» по которому соответственно индекса нет.
После чего заполняем данные для проведения эксперимента.
Наименование |
Реквизит не индексирован |
Реквизит индексированный |
|
Кресло мягкое |
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, в котором блокируются граничные записи, опытным путем установленно, что блокируется только нижняя граничная запись.
Выводы: При запросе к регистру возможна блокировка всей таблицы регистра, если в плане запроса используется сканирование, либо блокировка конкретных строк, если используется поиск по индексу. При запросе к документу или справочнику возможна либо блокировка строки, когда невозможно изменение любого реквизита, если используется кластерный индекс, либо блокировка поля объекта, если используется поиск или сканирование обычного индекса.
Что-то я не понял, о чем Вы хотите рассказать. Блокируются данные в той таблице, из которой были прочитаны. Т.е. если происходит clustered index seek — блокируются строки таблицы кластерного индекса, т.е. по сути своей строки основной таблицы. Если делается seek по некластерному индексу — блокируются его строки, соответственно, когда мы изменяем индексированный реквизит, мы пытаемся обновить индекс по этому реквизиту, а он блокирован. Блокировки же поля строки вообще не бывает. На основании чего в таблице указаны накладываемые при различных scan блокировки — вообще не понятно, нет у вас сканов в плане запроса.
Кстати, а чем table scan отличается от clustered index scan, Вы разобрались?
да статья невнятная, плюс не указана структура индекса, плюс не показано какие блокировки и как накладываются и выводы неверные как уже сказали нет блокировки поля, есть блокировки строк или страниц, ключей диапазонов и таблиц.
> блокируется только нижняя граничная запись.
Подробнее.
Лучше об этом прочитать в документации.
MSDN: Число установленных блокировок Range равно n+1, где n — это число строк, удовлетворяющих запросу.
Вы участник курсапо опимизации 1С ?
Вам нужно еще раз внимательно пересмотреть курс. Андрей Бурмистров четко говорит, что в автоматическом режиме блокировок всегда блокируется вся таблица, в управляемом — только нужные записи.
(3) zzz14, однозначно, да! Этот курс хорош, но его еще нужно переосмыслить!
(4) DoctorRoza, это не так. Гранулярность блокировок в MS SQL не зависит от режима управления блокировок в 1С.
(4) DoctorRoza,
Андрей Бурмистров этого не говорил.
(4) DoctorRoza, вероятно, Андрей говорит про Postgre или файловую БД. Ибо табличная блокировка в MSSQL — однозначно объект для разбирательства даже в режиме автоблокировок.
(3) zzz14, по большому счету это уже непринципиально, т.к. блокировка области в любом случае скорее всего избыточна. И стало практически неважным с появлением режима управляемых блокировок, когда транзакция осуществляется в read_committed. Безусловно, можно говорить о том, что блокировка существует, пока в транзакции выполняется долгий запрос, но долгий запрос, да еще и с избыточными блокировками — сам по себе объект для разбирательства.
(4) DoctorRoza, да бред.
Это не верно.
Автоматический режим отличается только уровнем изоляции.
Грянулярность тут ни при чем.
(1) asved.ru,
Примерно вот это я и хотел сказать, в зависимости от того что именно читается и как, может блокироваться либо вся таблица, либо «строка»(если смотреть на метаданные 1С) таблицы, либо «поле» (опять же если смотреть на метаданные 1С) таблицы
Я не стал приводить все этапы тестирования, например для регистров, это итоговая таблица.
В одном случае идет просмотр кластерного индекса, в другом таблицы? Нет?
(3) zzz14,
Спасибо за ссылку, прочту. Да, вы правы, прошел недавно этот курс.
(10) Agamest,
Вот так на сертификационном экзамене и скажите. Александр очень обрадуется.
Повторяю: в данном случае блокируется строка некластерного индекса. Все иные формулировки ошибочны и говорят только о непонимании механизма работы блокировок.
Логично. Но возникает вопрос: а кластерный индекс — это таблица или нет? И что такое просмотр? Не забываем про существование оператора seek … where.
Благодарю, сделал определенные выводы.
(12) asved.ru,
Повторяю: в данном случае блокируется строка некластерного индекса. Все иные формулировки ошибочны и говорят только о непонимании механизма работы блокировок.
Спасибо за поправку, буду знать что на экзамене нельзя абстрагироваться от понятий БД
Кластерный индекс на уровне листьев хранит данные, таблица включена в индекс. Соответственно просмотр кластерного индекса это просмотр его листьев. При seek where мы переходим с помощью seek на определенный уровень дерева, после чего просматриваем его листья и сравниваем с where. Я не прав?
(13) Agamest, абстрагироваться от понятий БД можно и нужно, если речь идет о процессе, протекающем выше уровня БД, к примеру, об управляемых блокировках. Но — при разборе управляемых блокировок и ожиданий на них нельзя забывать и о том, что они в любом случае сопровождаются блокировками СУБД согласно уровню изоляции транзакции.
Вот есть у нас непериодический регистр сведений, три измерения, несколько неиндексированных ресурсов. В запросе накладывается условие
1) на второе измерение
2) На первое, третье измерения и ресурс
Поставьте эксперимент, какими операторами в данных случаях будет выполняться чтение. Рассмотрите случаи с небольшим и значительным количеством записей. Ну и с различной селективностью по заданному условию.
Блокировку таблицы справочника целиком можно наблюдать при эскалации блокировок.
Для этого достаточно, что бы в операторе «Поиск ключа» (Key Lookup) было обработано более 5000 строк индекса (параметр настраиваемый). Думаю именно этот эффект вы на регистрах сведений и наблюдали.
(15) Sergey.Noskov, вы все еще не отключаете эскалацию по количеству? Тогда мы идем к вам! 😉