Про нюансы работы режима, когда в регистре бухгалтерии или в регистре накопления разрешено и включено разделение итогов, говорилось выше. Но этот механизм работает так, как было описано, даже когда речь идет не об избыточных блокировках, а о необходимых.
Далее же речь пойдет именно об избыточных блокировках. Потому что, в отличие от запросов на запись, при написании запросов на чтение у разработчика прикладного решения (конфигурации) есть много возможностей поставить избыточные блокировки. Как говорилось ранее в разделе 3.9, посвященном ошибкам блокировок, это приводит к таким ошибкам даже тогда, когда запись может осуществляться и осуществляется параллельно.
Далее, как отмечалось там же, работа некоторых механизмов «1С» приводит к избыточным блокировкам именно, точнее чаще, при чтении.
#Если &ИспользоватьОграничениеПоОрганизации #Тогда
ТекущаяТаблица
ИЗ
#ТекущаяТаблица КАК ТекущаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ
СоставГруппы.Ссылка КАК ГруппаПользователей
ИЗ
Справочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппы
ГДЕ
СоставГруппы.Пользователь = &ТекущийПользователь) КАК ГруппыПользователей
ПО (ИСТИНА)
ГДЕ
НЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULL
И
(an>НЕ 1 В
(ВЫБРАТЬ ПЕРВЫЕ 1
1
ИЗ
РегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступа
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей
КАК НастройкиПравДоступаПользователей
ПО
НастройкиПравДоступаПользователей.ОбъектДоступа = ТекущаяТаблица.#Параметр(1)
И НастройкиПравДоступаПользователей.ВидОбъектаДоступа =
НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа
И НастройкиПравДоступаПользователей.ОбластьДанных =
ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка)
И НастройкиПравДоступаПользователей.Пользователь =
ГруппыПользователей.ГруппаПользователей
ГДЕ
НазначениеВидовОбъектовДоступа.ГруппаПользователей =
ГруппыПользователей.ГруппаПользователей
И НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа
В (ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации))
И НастройкиПравДоступаПользователей.ОбъектДоступа ЕСТЬ NULL))
#КонецЕсли
Рис. 3.11.1. Пример запроса, дописываемого к основному подсистемой RLS. 1С:УПП 1.3.39.1, роль «Бухгалтер МСФО», ограничение чтения по организации (для указанной роли, в частности, используется на регистр бухгалтерии «Хозрасчетный»)
Такие дописываемые запросы осложняют жизнь не только тем, что приходится получать дополнительные данные, и даже, можно сказать, что совсем не тем. Основная проблема, которую они создают, состоит в том, что наличие подобных соединений очень сильно мешает использовать поиск по индексу и очень часто приводит к сканированию индекса или таблицы, то есть и к избыточным блокировкам, и к увеличению длительности выполнения запросов.
Вспомним Светочку с Леночкой из раздела 3.9.
Для борьбы за повышение производительности труда бумажные документы, с которыми работали Светочка и Леночка, «проиндексировали». Для этого, во-первых, документы стали класть в пластиковые файлы отдельного цвета, в зависимости от того, за какой месяц документ; во-вторых, цветной скрепкой стали обозначать, к какой организации документ относится (периодический регистр сведений с одним измерением или регистр накопления с одним измерением).
После этого стало достаточно давать каждой из девушек задания по работе со своими отдельными организациями, и работа наладилась (возможность параллельной работы).
Однако систему решили улучшить: работу с документами решили не только регулировать заданием, но и ограничением доступа.
В один прекрасный день Светочка получила следующее задание: «обработать документы за сентябрь (пластиковые файлы красного цвета) по организации «А-один» (синяя скрепка), учтя при этом, что она может работать только с документами организаций «А-один» и «Б-два» (красная скрепка)». Леночка получила задание: «обработать документы за сентябрь (пластиковые файлы красного цвета) по организации «В-три» (зеленая скрепка), учтя при этом, что она может работать только с документами организаций «В-три» и «Г-четыре» (желтая скрепка)».
Девушки напряглись. Светочка смогла сопоставить второе условие с третьим и сразу взяла только красные файлы с синей скрепкой. Леночка не смогла. Она сначала взяла красные файлы с зелеными и желтыми скрепками, но почти сразу файлы с желтыми скрепками вернула на место (избыточная блокировка на чтение, не приведшая к конфликту).
Поскольку обе девушки выполнили работу, эксперимент был признан удачным, и вскоре его распространили на всю фирму. Придя на работу, Светочка получила следующее задание: «обработать документы за сентябрь (пластиковые файлы красного цвета) по организации «А-один» (синяя скрепка), учтя при этом, что список ограничений (организаций, контрагентов, видов документов и др.), с которыми она может работать, висит на стенде в административном здании».
Периодов (месяцев) в качестве ограничений указано не было. Кроме того, все файлы были отсортированы по цветам, и пластиковые файлы красного цвета лежали рядом (кластерный индекс). Что это за условия, Светочка не знала, и сможет ли она их запомнить, сомневалась. Поэтому она, не задумываясь, взяла все красные файлы, пошла с ними в административный корпус, там прочитала условие и, постоянно с ним сверяясь, выбрала по нему те документы, с которыми ей можно работать, из них выбрала файлы с синей скрепкой, остальные вернула на место.
Леночка это видела. Она заметила, что вся эта операция не заняла особенно много времени и что ходить в административный корпус Светочке пришлось только один раз. Поэтому она решила применить ту же самую тактику. Одна незадача: ее тоже попросили обработать документы за сентябрь (пластиковые файлы красного цвета), хотя и по другой организации. Но поскольку Леночке согласно ее тактике для проверки условий требовались все документы из красных файлов (попытка установить избыточную блокировку на чтение), она их снова так и не дождалась и ушла в шесть вечера домой, так и не начав работать (таймаут).
Данный пример, кроме иллюстрации возникновения избыточной блокировки при чтении, использующем ограничения на уровне записей, демонстрирует еще одну закономерность. Чем более сложные и универсальные механизмы ограничения доступа строятся, тем менее следует надеяться, что оптимизатор СУБД распознает эти ограничения как имеющиеся у таблиц индексированные поля, хотя бы они и были таковыми, и тем выше вероятность, что будет иметь место сканирование индекса или таблицы.
Одним из вариантов решения проблем, когда видно, что избыточные блокировки возникают именно при чтении и именно при работе RLS, может быть отключение RLS, притом только на время транзакции, с отработкой исключительной ситуации, например, следующим кодом:
ТекущееЗначениеПараметра = ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей;
Попытка
ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = Ложь;
Запрос.Выполнить();
ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = ТекущееЗначениеПараметра;
Исключение
ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей = ТекущееЗначениеПараметра;
ВызватьИсключение;
КонецПопытки;
Рассмотрим частный и, повторим, заведомо ошибочный случай, когда разделение данных используется как разграничитель доступа по организациям.
Ситуация поворачивается наоборот: теперь пользователь с максимальными полномочиями оказывается в проигрыше.
Светочке и Леночке выделили по шкафу. Их документы теперь кладут только в эти шкафы. Девушкам не приходится ждать друг друга, они могут нормально работать. Но теперь проблемы начались у их начальника. Чтобы работать с документами, ему надо открыть и держать открытыми оба шкафа, он не может эффективно использовать поиск и брать стопку документов одним движением.
Если использовать независимый разделитель, то ни у одного пользователя физически не будет доступа ко всем данным. Например, Светочка будет иметь доступ к документам организации «А-один», Леночка к документам организации «В-три», но невозможно будет создать роль, которая имела бы доступ ко всем документам.
Если использовать независимый и совместный разделитель, то такая роль будет возможна. Появится возможность разрешить некоторым пользователям заходить в базу без указания значения разделителя, и эти пользователи будут видеть все данные. Но эффективной работы с этими данными не получится. Поскольку во всех индексах первым полем будет идти разделитель (точнее хеш-функция разделителей, см. раздел 3.13 «Сведения об индексах базы»), а пользователь с максимальными полномочиями будет работать без указания разделителя, то все запросы будут выполняться со сканированием: медленно и с избыточными блокировками. Это будет очень печально, потому что максимальные полномочия обычно предоставляют не рядовым пользователям, а наиболее толковым из них, а также начальству. И выйдет так, что именно у наиболее грамотных пользователей и у начальства запросы будут работать хуже. Как описывалось раньше, избыточные блокировки приведут к тому, что возможности параллельной работы транзакций серьезно уменьшатся.