Теория

Теория

3.1. Ключевые операции

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

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

■ ключевая операция всегда начинается на клиенте;

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

■ ключевая операция всегда заканчивается на клиенте.

 

То есть мы не можем разбить на несколько КО действие, которое является единым с точки зрения пользователя. В этом нет смысла, т. к. требования к частям операции не могут быть определены (пользователю все равно).Обычно нежелательность состояния рассматривается с точки зрения пользователя: проблема – это симптом, который видит пользователь, и в данном случае это недостаточно быстрое выполнение системой какой-либо важной для него операции.

Оговорка заключается в том, что при проведении нагрузочных тестов в качестве ключевых операций может выступать как раз время выполнения действий на сервере, потому что организовать это проще и дешевле. Это имеет право на существование, если достоверно установлено, что вызов кода обработкой с сервера, а не имитацией выполнения действия на клиенте, не исказит результатов. Например, вам надо удостовериться, что с точки зрения решаемой задачи допустимо вместо нажатия кнопки ОК на форме использовать вызов ДокументОбъект.Записать(…) сразу с сервера.Перед началом выполнения работ по оптимизации список ключевых операций должен быть составлен и зафиксирован. Размер списка не должен быть большим: разбор даже несложных проблем по каждой ключевой операции требует времени, и работы по списку из 20 операций точно займут не менее двух-трех месяцев.

Каждой ключевой операции должно быть назначено (пользователем) целевое время Т, а также приоритет.Целевое время – это время, за которое, с точки зрения пользователя, всегда должна выполняться ключевая операция, чтобы он считал работу системы отличной. Пользователь имеет право выразить завышенные ожидания, и тогда его надо письменно предупредить, что, возможно, вы вернетесь к этому разговору. Приоритет обычно определяется исходя из того, насколько проблема, вызываемая недостаточно быстрым выполнением действий системы, важна для пользователя. На практике при такой формулировке пользователь говорит: «Мне все проблемы важны одинаково» – и ставит всем одинаковый приоритет (как вариант выделяет несколько групп с разными приоритетами). На самом деле приоритет – это то, в каком порядке вы будете заниматься решением проблем пользователя. Поэтому заказчику так и надо сказать: «Оптимизацией будет заниматься один человек (это наиболее распространенный случай), поэтому он все равно будет решать задачи не параллельно, а последовательно. Пожалуйста, укажите, в каком порядке ему заниматься решением задач, если по итогам замеров окажется, что по всем операциям производительность недостаточно хороша».

В договоре обычно указывается следующее:

  • Перечень ключевых операций (нужно заполнить список вместе с клиентом)
  • Ключевая операция Приоритет Целевое время Т (сек.)
  • Перечень ключевых операций является предварительным и может быть изменен по взаимному согласию сторон.
  • Целевое время, указанное для каждой ключевой операции, также может уточняться в процессе выполнения работ по договору при наличии объективных причин, например, при несовпадении субъективной оценки пользователей и оценки APDEX.
  • Список ключевых операций и дополнительные пояснения к ним,обычно включаемые в договор.

После согласования списка ключевых операций замеры времени надо встроить в конфигурацию. Удобный способ это сделать – использовать подсистему «Оценка производительности» из состава Библиотеки стандартных подсистем «1С». Описание см. в главе «Инструкции», раздел 4.7 . 27 Теория3.2.

Методика APDEXКогда ключевая операция выполняется много раз, имеет смысл как-то сворачивать в число совокупность всех значений (получать интегральную характеристику) времени ее выполнения. И глядя с противоположной стороны, собранные замеры всегда имеет смысл рассма-тривать на достаточно большой выборке – не менее 100 замеров.Агрегировать можно по-разному: максимум, минимум, среднее, сумма, взвешенная сумма, методы математической статистики, методика APDEX. Не очень важно, как именно вы агрегируете или сворачиваете показатели. Важно, чтобы ваш заказчик понимал, в чем эта свертка заключается и почему она корректна. Фирма «1С» считает, что удобной и корректной является методика APDEX. Эта методика используется в составе подсистемы «Оценка производительности» из Библиотеки стандартных подсистем. Подробную информацию об этой мето-дике можно найти в Интернете (на английском языке): http://apdex.org/index.html, http://en.wikipedia.org/wiki/Apdex.Смысл методики таков: если какое-то действие должно выполниться за T секунд и оно выполняется за эти T секунд или быстрее, оно считается успешно выпол-ненным. Если оно выполняется несколько дольше – от Т до 4Т, оно считается напо-ловину успешным. Если оно выполняется очень долго – свыше 4Т, оно считается неуспешным.Если действия выполнялись неоднократно (N раз), далее достаточно подсчитать успешно выполненные действия (пусть их будет NS), подсчитать наполовину успешные (пусть их будет NT).Число (NS + NT /2) / N показывает отношение успешных и наполовину успешных действий к общему количеству действий. Что такое Т и 4Т, с точки зрения пользователя: ■ Т – это время, которое пользователя полностью удовлетворяет; ■ 4Т – это время, которое пользователя не удовлетворяет, но он дождался получения результата; ■ больше 4Т – пользователь не дождался получения результата, то есть операция вообще не выполнена.В таблице 3.2.1 показано, какие качественные значения соответствуют количе-ственным значениям показателей APDEX.Таблица 3.2.1. Соответствие качественных оценок значениям APDEXШкала APDEXЗначениеОценка от до0.00 0.50 неприемлемо0.50 0.70 очень плохо0.70 0.85 плохо (в некоторых интерпретациях –удовлетворительно)0.85 0.94 хорошо0.94 1.00 отлично28 Настольная книга 1С:Эксперта по технологическим вопросамВ случае 100-кратного выполнения5 действия на практике это выглядит так, как показано в таблице 3.2.2 .Таблица 3.2.2. Примеры комбинаций N, NS и NT для 100-кратного выполнения действияи соответствующие им оценки APDEX (показаны комбинациидля нижней границы диапазона, соответствующего оценке)(NS+NT/2)/N Оценка NS (успешных) NT (наполовинууспешных) N–NS–NT(не уложившихся в 4Т)0,94 – 1 отлично 94 0 60,94 – 1 отлично 88 12 00,85 – 0,93 хорошо 85 0 150,85 – 0,93 хорошо 70 30 00,70 – 0,84 плохо 70 0 300,70 – 0,84 плохо 40 60 00,50 – 0,69 очень плохо 50 0 500,50 – 0,69 очень плохо 0 100 00,00 – 0,49 неприемлемо Все, что еще хуже, чем две предыдущие строкиЗаказчики не сразу принимают такую схему, но для массовых замеров она действи-тельно хороша, так как учитывает не двоичную логику результата (уложились/ не уложились), а более сложную (уложились полностью/уложились в рамках допу-стимого/не уложились).Соответствие качественной оценки «хорошо» значению показателя 0,85 и выше – это для бизнеса, т. к. решаются его задачи. При этом некоторые операции выполняются долго или не выполняются вообще (пользователи «страдают»6). Но, поскольку может оказаться дешевле оплачивать «страдания» пользователей, чем оптимизировать систему до 1,00, это приемлемо с точки зрения бизнеса. Повторим еще раз: можно использовать любой подходящий для вашей ситуации способ свертки7 , лишь бы у вас с заказчиком по этому поводу было единое мнение. Если вы идете по пути встраивания подсистемы «Оценка производительности» из Библиотеки стандартных подсистем, то по сырым данным регистра сведений «Замеры времени» вы можете самостоятельно построить любую подходящую функцию, позволяющую яснее представить результат себе и заказчику. Свертка по методике APDEX в этой подсистеме, однако, уже реализована, и это еще один хороший повод пользоваться именно ей.5 Как говорилось выше, для получения необходимой точности нужно не менее 100 замеров. Если речь идет не о частых, а о редких или даже единичных событиях большой длительности (например, о выполнении каких-то регламентных операций), то описанный подход не годится: очень велика становится разница, выполняется операция, скажем, 2 часа или же 8. Если такая ключевая операция находится в числе прочих (коротких и частых), то надо смотреть по ситуации, что с ней делать. Можно считать для нее APDEX просто для сохранения единого подхода к замерам, соответственно подобрав целевое время, но можно сразу выделять ее в отдельную задачу, с результатом в виде достижения обозначенного времени выполнения. 6 Почему «страдания» заключено в кавычки, и что страдает на самом деле, см. раздел 6.1 .7 Но только не в том случае, если вы работаете с «1С» по проекту ЦКТП – тогда использование именно методики APDEX будет обязательным.29 ТеорияСуществует обратная задача – получить целевое время по заданному значению APDEX, если заказчик затрудняется это целевое время назвать. На практике, правда, в такой постановке эта задача встречается редко: список ключевых операций согласовывается до встраивания замеров в базу, а предлагаемая методика основывается на том, что замеры в базу уже встроены. Более вероятен вариант – использовать этот подход при необходимости переназначения и повтор-ного согласования целевого времени, изначально заданного чересчур жестко. Задачу необязательно решать вручную. В подсистему ОП встроен механизм автома-тического подбора времени Т под заданное значение APDEX.Если же требуется все-таки ручное решение, то порядок действий должен быть таким:1. Получить у заинтересованных пользователей субъективную оценку произво-дительности этой операции в терминах APDEX: Неприемлемо, Очень плохо, Плохо, Хорошо, Отлично. Установить значение APDEX, равное середине диапа-зона: соответственно, 0,25, 0,6, 0,775, 0,9, 0,95.2. Собрать информацию – сколько на самом деле выполняется эта операция в системе. 3. Подобрать такое значение T, чтобы APDEX, рассчитанный для него, был примерно равен значению, назначенному в п. 1. В случае использования подсис- темы «Оценка производительности» из БСП это можно делать непосредственно в режиме исполнения. 4. Проверить правильность полученного значения Т, если подбор осуществлялся каким-то другим способом.5. Продолжать получать значение APDEX для данной операции, исходя из нового времени Т, убедиться в том, что получаемая оценка APDEX соответствует субъективной оценке заказчика (в том числе если имело место переназначение и повторное согласование целевого времени).3.3. Критичные ошибкиК критичным ошибкам относятся: ■ ошибки блокировок, ■ системные ошибки, ■ ошибки защиты, ■ аварийные завершения процессов кластера серверов «1С:Предприятия», ■ зависание процессов кластера серверов «1С:Предприятия».30 Настольная книга 1С:Эксперта по технологическим вопросамОшибки блокировокОшибкой блокировки называется ошибка, возникающая при превышении времени ожидания на блокировке (lock request time out) или неразрешимый конфликт блокировок (взаимоблокировка – deadlock).Системные ошибкиСистемной ошибкой называется ошибка данных информационной базы или ошибка платформы, которая не позволяет пользователю выполнить какое-либо прикладное действие с системой. Любые функциональные ошибки кода конфигурации не являются системными ошибками.Аварийные завершения процессов кластера серверов «1С:Предприятия»Падением кластера серверов «1С:Предприятия» называется самопроизвольная выгрузка любого процесса кластера серверов «1С:Предприятия» или всех его процессов одновременно.Зависание процессов кластера серверов «1С:Предприятия»Зависанием кластера серверов «1С:Предприятия» называется состояние кластера, при котором он не отвечает на запросы пользователей, не позволяет создать новое клиентское подключение и т. п., но при этом остается загруженным в память рабочего сервера.3.4. Расчет доступности системыДостаточно частым требованием при проектировании системы является обеспе-чение требуемого уровня доступности и самой системы, и служб ее обслуживания и поддержки. Здесь доступность информации – состояние информации, характеризуемое способностью информационной системы обеспечивать беспрепятственный доступ к информации субъектам, имеющим на это полномочия.В требованиях часто указывается режим работы 24х7. Такой режим функциониро-вания закрепляется в документах, вводится в жизнь, а потом подвергается пере-смотру, и иногда достаточно болезненно.Связано это с тем, что любые информационные системы, и системы на платформе «1С:Предприятие» тут не исключение, требуют проведения регламентных операций. Чем более ответственные задачи выполняет эта система, тем строже надо следить, чтобы эти операции выполнялись. Конечно, если есть необходимость, ничто не мешает построить систему с полным дублированием всех компонентов, которая будет спокойно работать 24х7. Это возможно, но это дорого и сложно, и созданием такого комплекса надо специ-ально заниматься, сам собой он не возникнет.Список операций приведен в следующем разделе 3.5, а здесь скажем только, что часть операций требуется выполнять во время технологических окон, и работа других пользователей во время этих окон будет либо невозможна, либо сопряжена с некоторыми ограничениями.31 ТеорияПоэтому, например, можно сразу заявить режимы функционирования контуров системы так, как представлено в таблице 3.4.1 .Таблица 3.4.1. Штатные режимы функционирования контуров системыСерверы Гарантированноепредоставление услуг Обслуживаниеи поддержкаСерверы «1С» и СУБД в основном контуре 22х7* 8×5**Терминальные серверы, Web-сервер интеграции, сервер лицензий и другие серверы в основном контуре 22х7 8×5Серверы «1С» и СУБД в контуре разработки и (или) тестирования 22х7 8×5Терминальные серверы, Web-сервер интеграции, сервер лицензий и другие серверы в контуре разработки и (или) тестирования 22х7 8×5*22×7 – ежедневно, круглосуточно, с плановым 2-часовым технологическим окном и 8-часовым ежеквартально (длительность технологических окон приведена для примера). **8×5 – по рабочим дням с 9:00 до 18:00, с перерывом с 14:00 до 15:00.Чтобы отделить сервисные режимы от сбоев, можно указать, что требуется обеспе-чить функционирование системы в следующих режимах: ■ штатный режим (работа в течение 7 дней в неделю, 22 часа в сутки (22х7)); ■ сервисный режим (для проведения обслуживания, реконфигурации и пополнения новыми компонентами) – плановое 2-часовое технологическое окно ежедневно; ■ режим восстановления после сбоев.В штатном режиме работы система должна обеспечивать весь функциональный объем.Работа системы в сервисном режиме возможна в согласованное время (например, в ночное время, не более 2 часов в сутки, а также в дневное время, только в выходные или праздничные дни, не более 1 дня в месяц). В сервисном режиме работы допускается недоступность промышленных систем в связи: ■ с проведением регламентных работ по обслуживанию информационных баз «1С»; ■ проведением периодических профилактических работ, затрагивающих аппа-ратную или программную часть системы; ■ переносом запросов на изменение в продуктивную систему, влияющих на надежность и быстродействие системы; ■ обновлением программной или аппаратной части.В режиме восстановления после сбоев система может оказаться полностью или частично недоступна на период резервного копирования и восстановления в соот-ветствии с установленными в данной организации требованиями к надежности (см. таб. 3.4.2).Процент доступности, приведенный в таблице, рассчитывается как отношение коли- чества минимально допустимого фактического времени работы системы только 32 Настольная книга 1С:Эксперта по технологическим вопросамв штатном режиме за период (например, количество часов за квартал) к общему количеству часов за период.Например, указанный в таблице 3.4 .2 процент доступности 91,3 % рассчитывается так:В году 365 х 24 = 8760 часов.Сервисный режим: 2 часа в день + 8 часов в квартал. 2 х 365 + 8 х 4 = 762 часа.Потери времени на режим восстановления после сбоев идут за счет сервисного режима. Превышение не допускается.(8760 – 762) / 8760 = 0,913; отсюда 91,3 %.Обеспечение надежности функционирования системы обычно производится: ■ дублированием элементов серверного, коммутационного оборудования системы и при необходимости каналов передачи данных; ■ применением устройств бесперебойного электроснабжения серверов и коммута-ционного оборудования системы; ■ регулярным проведением регламентных профилактических работ по обслужи-ванию технических средств; ■ регулярным проведением регламентных работ по обслуживанию информаци-онных баз «1С»; ■ соблюдением технических требований эксплуатации элементов программно-тех-нических средств, обеспечивающих их бесперебойное функционирование; ■ применением организационных и технических мер защиты системы от несанкци-онированного доступа; ■ применением средств антивирусной защиты и их регулярным обновлением; ■ периодическим резервным копированием информации системы; ■ привлечением к обслуживанию системы высококвалифицированных специа-листов и повышением квалификации штатного обслуживающего персонала системы.33 ТеорияТ а б л и ц а 3 . 4 . 2 . П р и м е р п а р а м е т р о в н а д е ж н о с т и с и с т е м ыК о н т у р О б щ а я д о с т у п н о с т ь с и с т е м ы Д о с т у п н о с т ьп р е д о с т а в л я е м ы ху с л у г , с у ч е т о мс е р в и с н о г ор е ж и м а В о с с т а н о в л е н и е п о с л е с б о я П е р е р ы в ы н а о б с л у ж и в а н и еи п о д д е р ж к уЦ е л е в о е в р е м яв о с с т а н о в л е н и я( R T O ) , р а б .ч а с о в Ц е л е в а я т о ч к ав о с с т а н о в л е н и я( R P O ) , ч а с о в Д л и т е л ь -н о с т ь , р а б .ч а с о в П е р и о д и ч н о с т ьО с н о в н о й Н е п р е р ы в н а я , 2 4 х 7 – д л я а п п а р а т н о г о о б е с п е ч е н и я и с и с т е м н о г о п р о г р а м м н о г о о б е с п е ч е н и я , 2 2 х 7 – д о с т у п н о с т ь с о д е р ж и -м о г о б а з ы д а н н ы х 9 1 , 3 % 8 П р и н е о б х о д и -м о с т и в о с с т а н о в -л е н и я с р е з е р в н о й к о п и и – н а ч а л о т е к у щ е г о р а б о ч е г о д н я , п р и н е о б х о д и -м о с т и о т к а т а б а з ы – 1 ч а с 8 1 р а з в к в а р т а л2 Е ж е д н е в н ы е р е г л а -м е н т н ы е р а б о т ы ( у к а з а т ь в р е м я п р о в е д е н и я )Т е р м и н а л ь н ы е с е р в е р ы , W e b – с е р в е р и н т е г р а ц и и , с е р в е р л и ц е н з и й и д р у г и е с е р в е р ы в з о н е о с н о в н о г о к о н т у р а Н е п р е р ы в н а я , 2 4 х 7 – д л я а п п а р а т н о г о о б е с п е ч е н и я и с и с т е м н о г о п р о г р а м м н о г о о б е с п е ч е н и я 9 7 , 8 % 8 2 4 8 1 р а з в к в а р т а л3 Е ж е н е д е л ь н ы е р е г л а -м е н т н ы е р а б о т ы ( у к а з а т ь д е н ь н е д е л и и в р е м я п р о в е д е н и я )Р а з р а б о т к а и ( и л и ) т е с т и р о в а н и е 9 3 , 4 % – н е д о с т у п н о с т ь н е ч а щ е 2 д н е й в м е с я ц 8 4 , 7 % 1 6 2 4 8 1 р а з в к в а р т а л2 Е ж е д н е в н ы е р е г л а -м е н т н ы е р а б о т ы ( у к а з а т ь в р е м я п р о в е д е н и я )2 Е ж е д н е в н ы е р е г л а -м е н т н ы е р а б о т ы ( у к а з а т ь в р е м я п р о в е д е н и я )Т е р м и н а л ь н ы е с е р в е р ы , W e b – с е р в е р и н т е г р а ц и и , с е р в е р л и ц е н з и й и д р у г и е с е р в е р ы в к о н т у р е р а з р а б о т к и и ( и л и ) т е с т и р о в а н и я Н е п р е р ы в н а я , 2 4 х 7 – д л я а п п а р а т н о г о о б е с п е ч е н и я и с и с т е м н о г о п р о г р а м м н о г о о б е с п е ч е н и я , 2 2 х 7 – д о с т у п н о с т ь с о д е р ж и -м о г о б а з ы д а н н ы х 9 7 , 8 % 1 6 2 4 8 1 р а з в к в а р т а л3 Е ж е н е д е л ь н ы е р е г л а -м е н т н ы е р а б о т ы ( у к а з а т ь д е н ь н е д е л и и в р е м я п р о в е д е н и я )34 Настольная книга 1С:Эксперта по технологическим вопросам3.5. Регламентные работыДля обеспечения устойчивой работы требуется проведение регламентных меро-приятий (см. таблицу 3.5.1).Для проведения регламентных мероприятий с частотой «ежедневно» (исключая резервное копирование) должно быть выделено ежедневное технологическое окно. Длительность технологического окна зависит от особенностей системы.Более подробный регламент должен быть разработан дополнительно. В нем должны быть указаны ответственные (должности, функциональные роли или фамилии), способ отчетности (по эл. почте, вручную по журналам, через SMS), способ выпол-нения (автоматизированно, через ЦКК или вручную).При составлении регламента надо иметь в виду, что для некоторых регламентных операций время их выполнения и требующиеся для их выполнения ресурсы зависят от того, насколько редко эти операции делают. Это относится и к операциям из этого списка (например, обновление статистик), и к не входящим в него, и даже к тем операциям, которые не относятся к обеспечению устойчивости системы (обмены, восстановление последовательностей). Поэтому если какая-то операция не успевает выполниться за отведенное время в период бездействия пользователей или за время технологического окна, есть смысл попробовать делать ее не реже, а, наоборот, чаще. Может случиться (и часто случается) так, что выполнение операции каждые 5–15 минут из-за малого объема данных проходит настолько быстро, что не успевает никому помешать так сильно, чтобы это заметили.35 ТеорияТ а б л и ц а 3 . 5 . 1 . П р о в е д е н и е р е г л а м е н т н ы х м е р о п р и я т и йМ е р о п р и я т и е Ч а с т о т а В ы п о л н е н и е в ов р е м я т е х н о л .о к н а О т в е т с т в е н н ы й О т ч е т н о с т ь С п о с о бв ы п о л н е н и яК о н т р о л ь з а г р у ж е н н о с т и о б о р у д о в а н и я с е р в е р а п р и л о ж е н и й , с е р в е р а С У Б Д , т е р м и н а л ь н ы х с е р в е р о в . К о н т р о л и р о в а т ь п а р а м е т р ы : ○ и н т е н с и в н о с т ь о б м е н а м е ж д у д и с к о в о й п о д с и -с т е м о й и о п е р а т и в н о й п а м я т ь ю ; ○ и с п о л ь з о в а н и е в ы д е л е н н о й п а м я т и ; ○ з а г р у ж е н н о с т ь п р о ц е с с о р о в ; ○ о ч е р е д ь к п р о ц е с с о р а м ; ○ о ч е р е д ь к д и с к а м ; ○ с к о р о с т ь п е р е д а ч и д а н н ы х ч е р е з с е т ь П о с т о я н н о В т о м ч и с л е С м . И н с т р у к ц и и 4 . 1К о н т р о л ь в р е м е н и в ы п о л н е н и я к л ю ч е в ы х о п е р а ц и й Е ж е д н е в н о .П р и и с п о л ь -з о в а н и и Ц К К к о н т р о л ь и д е т п о с т о я н н о В т о м ч и с л е В о з м о ж н о ч е р е з Ц К К . К а к т о л ь к о п о к а з а т е л ь п р о и з в о д и т е л ь н о с т и в ы х о д и т и з к о р и д о р а , Ц К К с р а з у р а с с ы л а е т о п о в е щ е н и яК о н т р о л ь к о л и ч е с т в а о ш и б о к , в т . ч . о ш и б о к б л о к и -р о в о к , п о т е х н о л о г и ч е с к о м у ж у р н а л у Е ж е д н е в н о .П л а н и р у е т с я в к л ю ч и т ь в Ц К К , с т а н е т в о з м о ж н ы м п о с т о я н н ы й к о н т р о л ь В т о м ч и с л е С м . И н с т р у к ц и и 4 . 5К о н т р о л ь д о с т у п н о с т и с и с т е м ы П о с т о я н н о В т о м ч и с л е В о з м о ж е н к о н т р о л ь и о п о в е щ е н и я ч е р е з Ц К КК о н т р о л ь у с т о й ч и в о с т и ( о б р а з о в а н и е д а м п о в ) Е ж е д н е в н о .П р и и с п о л ь -з о в а н и и Ц К К к о н т р о л ь и д е т п о с т о я н н о В т о м ч и с л е В о з м о ж е н к о н т р о л ь и о п о в е щ е н и я ч е р е з Ц К КК о н т р о л ь н а л и ч и я с в о б о д н о г о м е с т а н а д и с к а х П о с т о я н н о В т о м ч и с л е В о з м о ж е н к о н т р о л ь и о п о в е щ е н и я ч е р е з Ц К КП е р е з а п у с к р а б о ч и х п р о ц е с с о в и л и а г е н т о в с е р в е р а « 1 С » М и н и м у м е ж е д н е в н о Д а С м . И н с т р у к ц и и 4 . 3Р е з е р в н о е к о п и р о в а н и е б а з ы П о о т д е л ь н о м у р е г л а м е н т у Н е т36 Настольная книга 1С:Эксперта по технологическим вопросамМ е р о п р и я т и е Ч а с т о т а В ы п о л н е н и е в ов р е м я т е х н о л .о к н а О т в е т с т в е н н ы й О т ч е т н о с т ь С п о с о бв ы п о л н е н и яО б р е з а н и е б а з ы и ж у р н а л а т р а н з а к ц и й .Р е к о м е н д у е т с я д л я ф а й л а ж у р н а л а т р а н з а к ц и й п р и з н а ч и т е л ь н ы х о б ъ е м а х н е и с п о л ь з у е м о г о п р о с т р а н с т в а в н е м и н е х в а т к е м е с т а н а д и с к е П е р и о д и ч н о с т ь к о н т р о л я – н е р е ж е 1 р а з а в м е с я ц Н е тР е и н д е к с а ц и я б а з ы 8 Е ж е д н е в н о Д а С м . И н с т р у к ц и и 4 . 4Р е ж и м « Т е с т и р о в а н и е и и с п р а в л е н и е б а з ы » Н е р е ж е 1 р а з а в к в а р т а л Н е тП е р е с ч е т и т о г о в Е ж е м е с я ч н о . П р и и с п о л ь з о -в а н и и р е ж и м а р а з д е л е н и я и т о г о в – е ж е д н е в н о Е ж е д н е в н о е – д аО б н о в л е н и е с т а т и с т и к 8 Е ж е д н е в н о , т а к ж е р е к о м е н -д у е т с я д е л а т ь н е п о с р е д с т в е н н о п о с л е з а г р у з о к б о л ь ш и х о б ъ е м о в д а н н ы х Д а С м . И н с т р у к ц и и 4 . 4О ч и с т к а п р о ц е д у р н о г о к е ш а 1 0 Н е п о с р е д с т в е н н о п о с л е о б н о в -л е н и я с т а т и с т и к и Д а С м . И н с т р у к ц и и 4 . 4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _8 П р и и с п о л ь з о в а н и и С У Б Д S Q L S e r v e r .9 В ц е л о м э т и р е к о м е н д а ц и и у с т а р е л и . И м и м о ж н о п о л ь з о в а т ь с я , н о с о г о в о р к а м и : о б н о в л е н и е с т а т и с т и к м о ж е т н е п о м о ч ь и с п р а в и т ь п л о х о й п л а н . Е с л и о б н о в л е н и е с т а т и с т и к п о м о г а е т , т о э т о у к а з ы в а е т н а т о , ч т о з а п р о с м н о г о к р а т н о п е р е у с л о ж н е н . Н у ж н о е г о р а д и к а л ь н о у п р о щ а т ь . П р и н о р м а л ь н о ( т о е с т ь п р о с т о ) н а п и с а н н ы х з а п р о с а х о б н о в л е н и е с т а т и с т и к в о о б щ е н е н у ж н о – д о с т а т о ч н о т о г о , к о т о р о е д е л а е т а в т о м а т и ч е с к и С У Б Д . Н е о б я з а т е л ь н о и х в ы п о л н я т ь в о в р е м я т е х н о л о г и ч е с к о г о о к н а , х о т я н а п р а к т и к е э т о и у д о б н е е .1 0 С м . п р е д ы д у щ у ю с н о с к у .37 Теория3.6. Транзакции. Уровни изоляции транзакций.Явные и неявные транзакции. Вложенныетранзакции. Откат транзакцийТранзакция вообще – это минимальная логически осмысленная операция, которая имеет смысл и может быть совершена только полностью.Транзакция в информатике – это группа логически объединенных последовательных операций по работе с данными, обрабатываемая или отменяемая целиком. То есть все изменения данных, вносимые транзакцией, должны быть либо зафиксированы (COMMIT), либо отменены (ROLLBACK).Свойства транзакции: ■ неделимость (атомарность): □ все или ничего, □ должна или пройти, или не пройти полностью, ■ изоляция: □ действия других пользователей не должны повлиять на мои результаты.Когда речь идет об однопользовательском режиме, транзакция нужна для защиты от аппаратных сбоев. Но когда требуется обеспечить работу нескольких пользователей (прохождение нескольких транзакций) одновременно, появляются новые задачи. Например, в транзакции 1 выполняется следующий набор действий (проведение документа):1. Проконтролировать остатки по регистру накопления 1. 2. Записать движения по регистру накопления 1.3. Проконтролировать остатки по регистру накопления 2. 4. Записать движения по регистру накопления 2.В транзакции 2 выполняется точно такой же набор действий (проведение документа, для определенности будем считать, что такого же и с такими же данными), но начи-нается она, например, когда первая транзакция дошла до шага 3. В этом случае у системы должно быть некое правило, в соответствии с которым она определит дальнейший ход событий для транзакции 2. Система может, например: ■ разрешить транзакции 2 выполнять все действия, не обращая внимания на тран-закцию 1 (это, вообще говоря, совсем не транзакционный механизм); ■ разрешить транзакции 2 выполнять чтение, не обращая внимания на транзак- цию 1; ■ не разрешить транзакции 2 выполнять никаких действий до окончания транзак- ции 1, поставив ее в очередь, поскольку речь идет об одних и тех же данных в регистре накопления 1.Уже из изложенного видно, что даже если разрешить транзакции 2 только чтение, то данные этого чтения могут оказаться неточными, потому что транзакция 1 может 38 Настольная книга 1С:Эксперта по технологическим вопросамбыть отменена. Но параллельность работы при этом выше. И наоборот, только после-довательный доступ к данным повышает точность и согласованность данных, но количество параллельно выполняемых транзакций может снижаться. К несогласованностям данных, которые следует принимать во внимание, относятся следующие: ■ потерянное обновление (англ. lost update) – если один и тот же блок данных одно-временно изменяют две разные транзакции, то будет зафиксировано только одно изменение, второе потеряется (при работе «1С» невозможно, поскольку в «1С» не бывает записи вне транзакции); ■ «грязное» чтение (англ. dirty read) – чтение данных, добавленных или измененных транзакцией, может дать неточный результат, потому что та транзакция впослед-ствии не подтвердится (откатится); ■ неповторяющееся чтение (англ. non-repeatable read) – при повторном чтении в рамках одной и той же транзакции оказывается, что ранее прочитанные данные изменены или удалены; ■ фантомное чтение (англ. phantom reads) – при повторном чтении в рамках одной и той же транзакции оказывается, что прочитаны строки, которых при преды-дущих чтениях не было (новые строки называют «фантомными»).То, насколько транзакции изолированы друг от друга (обратно – то, насколько в них допускаются несогласованные данные), называется уровнем изоляции транзакций. Уровни изоляции описаны с точки зрения того, какие из побочных эффектов парал-лелизма разрешены.Определяют следующие уровни изоляции (в порядке ее повышения): ■ Read Uncommitted (неподтвержденное чтение, изоляция незафиксированногочтения)11 . 8Указывает, что запросы могут считывать строки, которые были изменены другими транзакциями, но еще не были зафиксированы. Допускается чтение незафиксированных изменений текущей транзакции (параллельными транзакциями) и незафиксированных изменений параллельных транзакций (нашей и другими транзакциями). Самый низкий уровень, при котором транзакции изолируются до такой степени, чтобы только уберечь от считывания физически поврежденных данных. Возможны «грязные», неповторяемые чтения и фантомы. ■ Read Committed Snapshot (подтвержденное чтение с включенным параме-тром READ_COMMITTED_SNAPSHOT). Для СУБД MS SQL в «1С» поддерживается начиная с 8.3 (без режимов совместимости с 8.2). В СУБД ORACLE уровень с такими же свойствами используется «1С» и в версии 8.2.Уровень указывает, что запросы не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы. 11 В скобках – синонимы.39 ТеорияВ момент начала чтения транзакции будет выделен моментальный снимок (snapshot) базы данных, включающий в себя все изменения завершенных к этому моменту времени транзакций. Транзакция может читать этот снимок, получая чистые данные (без «грязного» чтения) и при этом никого не блокируя. «Грязные» чтения невозможны, возможны неповторяемые чтения и фантомы.Использование этого режима накладывает дополнительные требования по качеству кода (т. е. по качеству наложенных управляемых блокировок). Там, где раньше в транзакции при контроле остатков произошел бы таймаут на уровне СУБД, теперь будут просто прочитаны строки с предыдущими номерами, и, таким образом, не будут учтены изменения, вносимые транзакцией, начавшейся раньше нашей, но к моменту контроля остатков в нашей транзакции еще не завершившейся. Таким образом, могут возникнуть проблемы, которые будет очень сложно отловить. ■ Read Committed (подтвержденное чтение, изоляция зафиксированногочтения). Это режим по умолчанию для уровня Read Committed (параметр READ_COMMITTED_SNAPSHOT выключен).Как и уровень Read Committed Snapshot, указывает, что запросы не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы. При выполнении операций чтения текущей транзакцией используются разделяемые блокировки для предотвращения изменения строк другими транзакциями (время освобождения в общем зависит от того, что блокируется – строка, страница или таблица, но достаточно понимать, что все освобождается после выполнения запроса) и для предотвращения от считывания строк, измененных другими транзакциями, пока они не завершатся. «Грязные» чтения невозможны, возможны неповторяемые чтения и фантомы. ■ Repeatable Read (повторяемое чтение, изоляция повторяющегося чтения). Указывает на то, что другие транзакции не могут изменять данные, читаемые текущей транзакцией, до ее завершения.Как и предыдущий уровень, указывает, что запросы не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы.Разделяемые блокировки применяются ко всем данным, считываемым любым запросом транзакции, и сохраняются до ее завершения. Это запрещает другим транзакциям изменять строки, считываемые текущей транзакцией.«Грязные» и неповторяемые чтения невозможны. Возможны фантомы. ■ Snapshot (изоляция моментального снимка), отдельный уровень изоляциив SQL Server 2005. Дается для справки, в «1С» не поддерживается.Указывает на то, что данные, считанные любым запросом транзакции, будут согласованы на уровне транзакции с версией данных, существовавших в ее начале. Транзакция распознает только те изменения, которые были зафиксированы до ее начала (это отличие от Read Committed Snapshot). Запросы на чтение, 40 Настольная книга 1С:Эксперта по технологическим вопросамвыполняемые текущей транзакцией, не видят изменений данных, произведенных другими транзакциями после запуска текущей транзакции. «Грязные» и неповторяемые чтения невозможны. Фантомы невозможны. ■ Serializable (упорядоченный, изоляция упорядочиваемых транзакций, сериа-лизуемый, упорядоченные транзакции, сериализуемые транзакции). Отличие от Repeatable Read в том, что другие транзакции не могут вставлять новые строки со значениями ключа, которые входят в диапазон ключей, считываемых запросами текущей транзакции, до ее завершения.Остальные ограничения сохраняются: другие транзакции не могут изменять данные, считываемые текущей транзакцией, до ее завершения, и запросы не могут считывать данные, которые были изменены другими транзакциями, но еще не были зафиксированы.Этот уровень изоляции идентичен ситуации, при которой транзакции выполняются строго последовательно, одна после другой.«Грязные» и неповторяемые чтения, а также фантомы невозможны.В таблице 3.6 .1 показаны побочные эффекты параллелизма, допускаемые различ-ными уровнями изоляции.Таблица 3.6.1. Побочные эффекты параллелизма, допускаемые различными уровнями изоляцииУровень изоляции «Грязное» чтение Неповторяющееся чтение Фантомное чтениеRead Uncommitted Да Да ДаRead Committed Snapshot Нет Да ДаRead Committed Нет Да ДаRepeatable Read Нет Нет ДаSerializable Нет Нет НетУровень изоляции теоретически может устанавливаться как для всей СУБД, так и для одной транзакции и даже с определенными ограничениями (ограничений мало) изменяться в течение транзакции. 9Однако при работе с информационными системами на платформе «1С:Предпри-ятие» следует всегда понимать, что в случае, когда используются транзакции12 , уровень изоляции регулируется только изменением режима управления блокировкой данных. Эти уровни устанавливаются средствами платформы «1С:Предприятие» в свойствах конфигурации для всей базы. Также для отдельной транзакции уровень можно установить в качестве параметра процедуры глобального контекста НачатьТранзакцию() – такая установка параметра имеет смысл, если для свойства конфигурации «Режим управления блокировкой данных» выбрано значение «Автома- тический и Управляемый»13 . Какие уровни для каких СУБД используются, показано в таб. 3.6.2 . 1012 Как указывалось выше, записи вне транзакций в «1С» не бывает. Но читать вне транзакции можно, и таким образом получить «грязное» чтение. 13 Использование этого режима вне переходного процесса с автоматического режима управления блокировками на управляемый режим является ошибкой. Растягивание этого переходного процесса на несколько месяцев (а тем более лет) также является ошибкой.41 ТеорияТаблица 3.6.2. Блокировки СУБД, используемые в транзакции в зависимостиот режима управления блокировкой данных, версии платформы и от СУБДВидблокировки Уровень изоляции транзакцийДля 8.2 Для 8.3Автоматические блокировкиФайловая БД Таблиц Serializable SerializableMS SQL Server Записей Repetable Read или Serializable* Repetable Read или Serializable*IBM DB2 Записей Repetable Read или Serializable* Repetable Read или Serializable*PostgreSQL Таблиц Serializable SerializableOracle Database Таблиц Serializable SerializableУправляемые блокировкиФайловая БД Таблиц Serializable SerializableMS SQL Server 2000 Записей Read Committed Read CommittedMS SQL Server 2005 и выше Записей Read Committed Read Committed Snapshot IBM DB2 Записей Read Committed Read CommittedPostgreSQL Записей Read Committed Read CommittedOracle Database Записей Read Committed Read Committed* Repeatable Read используется для объектных сущностей (все, у чего есть поле Ссылка – справочники, документы и т. п.), Serializable – для необъектных. Платформа исходит из того, что объекты будут искаться по уникальной ссылке, поэтому проблема фантомного чтения для объектов неактуальна (платформа не позволит добавить объект с такой же ссылкой).Любая операция чтения данных, выполняемая вне транзакции, считается безот-ветственной. Поведение системы при безответственном чтении (например, при выполнении отчетов) отличается в различных режимах блокировок. Отличия безот- ветственного чтения в разных режимах работы управления блокировками (автомати-ческом или управляемом) для платформы 8.3 приведены в таблице 3.6 .3.Таблица 3.6.3. Отличия безответственного чтения в разных режимах работы блокировок для 8.3(при установленном режиме совместимости конфигурации с 8.3 и выше)Чтение вне транзакцииАвтоматические блокировкиФайловая БД «Грязное» чтениеMS SQL Server «Грязное» чтение IBM DB2 «Грязное» чтениеPostgreSQL Согласованное чтениеOracle Database Согласованное чтениеУправляемые блокировкиФайловая БД «Грязное» чтениеMS SQL Server 2000 «Грязное» чтениеMS SQL Server 2005 и выше Согласованное чтениеIBM DB2 «Грязное» чтениеPostgreSQL Согласованное чтениеOracle Database Согласованное чтениеЕсли для защиты изменений данных транзакция устанавливает блокировку, то это всегда исключительная (монопольная) блокировка Х, и эта блокировка держится до тех пор, пока транзакция не завершится, независимо от уровня изоляции, установленного для транзакции. Уровень изоляции транзакции влияет на то, ставится вообще блокировка или нет, и на что она ставится. Например, на уровне Serializable появляются блокировки Range.42 Настольная книга 1С:Эксперта по технологическим вопросамЕсли транзакция устанавливает блокировку для защиты чтения данных, то, когда речь идет об обычном чтении в транзакции, ставится разделяемая (совместимая) блокировка S, а когда о чтении ДЛЯ ИЗМЕНЕНИЯ – блокировка обновления U. Детальнее о совместимости блокировок говорится в следующей главе. Уровень изоляции транзакции влияет не только на то, ставится ли вообще блокировка и на что она ставится, но и на то, когда она снимается. Снятие блокировок (на уровне СУБД) происходит так: ■ блокировка, установленная «на запись», всегда остается до конца транзакции; ■ при использовании Repeatable Read или Serializable (автоматический режим управ- ления блокировками «1С») блокировка, установленная «на чтение» сохраняется до конца транзакции. Если после чтения идет запись, это может приводить к взаи-моблокировкам по причине повышения уровня блокировки ресурса (причины и обход см. в разделе 3.9); ■ при использовании Read Committed (управляемый режим управления блокиров-ками «1С») блокировка, установленная «на чтение», снимается после выполнения запроса. Это требует дополнительного блокирования прочитанных данных, если требуется обеспечить их неизменность (см. раздел 3.8). Сводные данные по всем режимам, доступным в «1С:Предприятии», приведены в таблице 3.6 .4 (недоступные режимы не приводятся).Таблица 3.6.4. Сводная таблица по всем режимам, доступным в «1С:Предприятии»Транзакция Уровень изоляции Действие Блокировка «Грязное»чтение Неповт.чтение ЧтениефантомовВне транзакции READ UNCOMMITTED чтение нет+ + +Вне тран-закции* READ COMMITTED SNAPSHOT* чтение нет-+ +Управляемая транзакция READ COMMITTED SNAPSHOT* чтение нет14 -+ +запись X -+ +READ COMMITTED чтение S (запрос) -+ +запись XАвтома-тическая транзакция REPEATABLE READ чтение объектов S – -+ чтение объектов”ДЛЯ ИЗМЕНЕНИЯ” Uзапись объектов X SERIALIZABLE чтение регистров S, RangeS – – – чтение регистров “ДЛЯ ИЗМЕ- НЕНИЯ” U, RangeUзапись регистров X, RangeX* Только начиная с 8.3 с режимом совместимости с 8.3 и выше________________14 Точнее ставится блокировка стабильности схемы (Sch-S), но она не влияет на блокировки транзакций, включая монопольные (X) блокировки.43 ТеорияТранзакции могут быть явными и неявными. Явные транзакции начинаются средствами языка «1С» процедурой глобального контекста НачатьТранзакцию(), завершаются процедурой глобального контекста ЗафиксироватьТранзакцию(), отменяются процедурой ОтменитьТранзакцию().Неявные транзакции начинаются, завершаются и отменяются средствами плат-формы. Любые операции, изменяющие данные (например, проведение и отмена проведения документов), выполняются только в транзакции. События прикладных объектов конфигурации, обработчики которых выполняются в неявной транзакции15 , приведены в таблице 3.6.5 . Речь идет и об обработчиках, которые вызываются через модули этих прикладных объектов, и об обработчиках, которые вызываются через подписки на события. 11 Таблица 3.6.5. Обработчики событий прикладных объектов, выполняемые в транзакцииИсточник Событие Выполняетсяв транзакцииБизнесПроцессОбъект.<Имя бизнес-процесса>ПередЗаписью Да ВнешнийИсточникДанныхТаблицаНаборЗаписей.<Имя внешнего источника>.<Имя таблицы внешнего источника данных>ВнешнийИсточникДанныхТаблицаОбъект.<Имя внешнего источника>.<Имя таблицы внешнего источника данных>ДокументОбъект.<Имя документа>ЗадачаОбъект.<Имя задачи>КонстантаМенеджерЗначения.<Имя константы>ПерерасчетНаборЗаписей.<Имя перерасчета>ПланВидовРасчетаОбъект.<Имя плана видов расчета>ПланВидовХарактеристикОбъект.<Имя плана видов характеристик>ПланОбменаОбъект.<Имя плана обмена>ПланСчетовОбъект.<Имя плана счетов>ПоследовательностьНаборЗаписей.<Имя последователь- но сти>РегистрБухгалтерииНаборЗаписей.<Имя регистра бухгалтерии>РегистрНакопленияНаборЗаписей.<Имя регистра накопления>РегистрРасчетаНаборЗаписей.<Имя регистра расчета>РегистрСведенийНаборЗаписей.<Имя регистра сведений>СправочникОбъект.<Имя справочника>15 Речь о неявной транзакции, инициированной средствами платформы при выполнении действий с прикладным объектом, и обработчиках, при выполнении этого действия автоматически выполняющихся. Но если просто взять и вызвать выполнение процедуры ОбработкаПроведения(), то само по себе это действие транзакцию не инициирует. Данное замечание верно для таблиц 3.6.5 –3.6.8.44 Настольная книга 1С:Эксперта по технологическим вопросамИсточник Событие Выполняетсяв транзакцииБизнесПроцессОбъект.<Имя бизнес-процесса>ПриЗаписи Да ВнешнийИсточникДанныхТаблицаНаборЗаписей.<Имя внешнего источника>. <Имя таблицы внешнего источника данных>ВнешнийИсточникДанныхТаблицаОбъект.<Имя внешнего источника>.<Имя таблицы внешнего источника данных>ДокументОбъект.<Имя документа>ЗадачаОбъект.<Имя задачи>КонстантаМенеджерЗначения.<Имя константы>ПерерасчетНаборЗаписей.<Имя перерасчета>ПланВидовРасчетаОбъект.<Имя плана видов расчета>ПланВидовХарактеристикОбъект.<Имя плана видов характеристик>ПланОбменаОбъект.<Имя плана обмена>ПланСчетовОбъект.<Имя плана счетов>ПоследовательностьНаборЗаписей.<Имя последователь- но сти>РегистрБухгалтерииНаборЗаписей.<Имя регистра бухгалтерии>РегистрНакопленияНаборЗаписей.<Имя регистра накопления>РегистрРасчетаНаборЗаписей.<Имя регистра расчета>РегистрСведенийНаборЗаписей.<Имя регистра сведений>СправочникОбъект.<Имя справочника>ЗадачаОбъект.<Имя задачи> ПередВыполнением ДаЗадачаОбъект.<Имя задачи> ПриВыполнении ДаДокументОбъект.<Имя документа> ОбработкаПроведения ДаДокументОбъект.<Имя документа> ПередУдалением16 ДаДокументОбъект.<Имя документа> ОбработкаУдаленияПро-ведения ДаСобытия расширений управляемых форм, обработчики которых выполняются в неявной транзакции, приведены в таблице 3.6.6 .________________16 В синтакс-помощнике выполнение обработчика события ПередУдалением в транзакции в явном виде указано только для ДокументОбъект, для остальных видов объектов связь обработчика с транзакциями не указана.45 ТеорияТаблица 3.6.6. Обработчики событий расширений управляемых форм, выполняемые в транзакцииИсточник Событие Выполняетсяв транзакцииРасширение управляемой формы для бизнес-процессаПриЗаписиНаСервере Да Расширение управляемой формы для документаРасширение управляемой формы для задачиРасширение управляемой формы для записи регистра сведенийРасширение управляемой формы для записи таблицы внешнего источника данныхРасширение управляемой формы для константРасширение управляемой формы для набора записейРасширение управляемой формы для объекта таблицы внешнего источника данныхРасширение управляемой формы для объектовРасширение управляемой формы для плана видов характе-ристикРасширение управляемой формы для справочникаСобытия расширений обычных форм, обработчики которых выполняются в неявной транзакции, приведены в таблице 3.6 .7.Таблица 3.6.7. Обработчики событий расширений обычных форм, выполняемые в транзакцииИсточник Событие Выполняетсяв транзакцииРасширение формы вида расчетаПриЗаписи Да Расширение формы документаРасширение формы задачиРасширение формы записи регистра сведенийРасширение формы константРасширение формы набора записей регистра бухгалтерииРасширение формы набора записей регистра накопленияРасширение формы набора записей регистра расчетаРасширение формы набора записей регистра сведенийРасширение формы объекта бизнес-процессРасширение формы узлаРасширение формы элемента вида характеристикРасширение формы элемента плана счетовРасширение формы элемента справочникаСобытия расширений управляемых форм, обработчики которых выполняются вне неявной транзакции, приведены в таблице 3.6.8 .46 Настольная книга 1С:Эксперта по технологическим вопросамТаблица 3.6.8. Обработчики событий расширений управляемых форм, выполняемые вне транзакцииИсточник Событие Выполняетсяв транзакцииРасширение управляемой формы для бизнес-процессаПередЗаписьюНаСервере Нет Расширение управляемой формы для документаРасширение управляемой формы для задачиРасширение управляемой формы для записи регистра сведенийРасширение управляемой формы для записи таблицы внешнего источника данныхРасширение управляемой формы для константРасширение управляемой формы для набора записейРасширение управляемой формы для объекта таблицы внешнего источника данныхРасширение управляемой формы для объектовРасширение управляемой формы для плана видов характеристикРасширение управляемой формы для справочникаРасширение управляемой формы для бизнес-процессаПослеЗаписиНаСервере Нет Расширение управляемой формы для документаРасширение управляемой формы для задачиРасширение управляемой формы для записи регистра сведенийРасширение управляемой формы для записи таблицы внешнего источника данныхРасширение управляемой формы для константРасширение управляемой формы для набора записейРасширение управляемой формы для объекта таблицы внешнего источника данныхРасширение управляемой формы для объектовРасширение управляемой формы для плана видов характеристикРасширение управляемой формы для справочникаРасширение управляемой формы для бизнес-процессаПослеЗаписи Нет Расширение управляемой формы для документаРасширение управляемой формы для задачиРасширение управляемой формы для записи регистра сведенийРасширение управляемой формы для записи таблицы внешнего источника данныхРасширение управляемой формы для константРасширение управляемой формы для набора записейРасширение управляемой формы для объекта таблицы внешнего источника данныхРасширение управляемой формы для объектовРасширение управляемой формы для плана видов характеристикРасширение управляемой формы для справочника47 ТеорияСобытия расширений обычных форм, обработчики которых выполняются вне неявной транзакции, приведены в таблице 3.6.9 .Таблица 3.6.9. Обработчики событий расширений обычных форм, выполняемые вне транзакцииИсточник Событие Выполняетсяв транзакцииРасширение формы вида расчетаПослеЗаписи Нет Расширение формы документаРасширение формы задачиРасширение формы записи регистра сведенийРасширение формы константРасширение формы набора записей регистра бухгалтерииРасширение формы набора записей регистра накопленияРасширение формы набора записей регистра расчетаРасширение формы набора записей регистра сведенийРасширение формы объекта бизнес-процессРасширение формы узлаРасширение формы элемента вида характеристикРасширение формы элемента плана счетовРасширение формы элемента справочникаПрочие события объектов, их форм, обычных и управляемых, и расширений этих форм выполняются вне неявных транзакций.Чтобы удостовериться, выполняется обработчик события в транзакции или нет, нужно открыть его в синтакс-помощнике, и если это так, в блоке «Описание» будет написано «возникает в транзакции», «вызывается… до окончания транзакции» и т. п.Наличие параметра Отказ в параметрах обработчика событий не служит признаком, того, что обработчик выполняется в транзакции: например, обработчик события ОбработкаПроверкиЗаполнения() содержит параметр Отказ, но выполняется вне неявной транзакции. Операции чтения могут выполняться в неявной транзакции. Это происходит, когда требуется обеспечить чтение согласованного набора данных. На текущий момент нам известно о двух случаях, когда это происходит: ■ При чтении в объектной технике объектов, имеющих табличные части17, например, запрос: 12ДокументПроведен =ДокументСсылка.Проведен;будет выполняться в неявной транзакции, если для документа данного типа в конфигураторе определена табличная часть, но вне транзакции, если табличных частей у документа нет. ■ При формировании отчетов, требующих согласованных данных. Например, если отчет строится с помощью построителя, то в большинстве случаев он выполняется, как и ожидается, без транзакции, но если в настройке отчета в группировках строк указать «По неделям», то при вызове метода ПостроительОтчета.Вывести(ТабличныйДокумент); инициируется транзакция.17 Анонсирован отказ от использования транзакций для этих целей в будущем.48 Настольная книга 1С:Эксперта по технологическим вопросамОбращаем внимание на то, что раз разговор идет о транзакционном чтении, то в этих случаях могут возникать (и возникают) конфликты блокировок в совершенно неожиданных местах: при работе с формами, в отчетах и, казалось бы, в безо-бидных обработках. Ситуация с отчетами ухудшается тем, что на выбор – выполня- ется чтение в транзакции или нет – влияет не код конфигурации, а пользовательские настройки. А чтение в объектной технике – это настолько важный вопрос, что ему посвящен отдельный раздел 3.15 «Особенности чтения в объектной модели».Узнать, выполняется чтение с транзакции или нет, можно в профайлере SQL Server. Настроив трассировку, например, в соответствии с разделом 4.12 «Работа в профай-лере. Как получить план запроса», нужно с помощью отладчика, выполнить подо-зрительную строку. Если транзакция имеет место, в трассировке появятся BEGIN TRANSACTION и COMMIT TRANSACTION.Транзакции, как явные, так и неявные, могут быть вложенными. Обычный случай, например, запись элемента одного справочника из процедуры ПриЗаписи модуля другого справочника или из подписок на события, обрабатываемых внутри тран-закции. Применение такого подхода при всем его удобстве, однако, может создавать проблемы производительности, поэтому пользоваться им надо аккуратно, а злоу-потреблять, создавая каскады записывающихся друг из друга объектов, не стоит вообще. Если внутри транзакции произошла исключительная ситуация, она откатывается. Если внутри транзакции были вложенные транзакции или она сама являлась вложенной, откатываются все транзакции, независимо от того, на каком из уровней вложенности это произошло. Проще говоря, никто не запрещает начинать одну транзакцию внутри другой, но ведет себя все это почти всегда как одна транзакция самого верхнего уровня, т. е. вложенные транзакции игнорируются. Нюансы поведения, связанные с отработкой некоторых ошибок в коде, приведены ниже. Если исключительную ситуацию отработать с помощью скобок Попытка… Исклю-чение… КонецПопытки, расположенных внутри транзакции, то транзакция не завершится в момент возникновения исключительной ситуации, она дойдет до следующего обращения к данным – чтения или записи, продолжая при этом блоки-ровать ресурсы, и откатится с сообщением: «В данной транзакции уже происходили ошибки!». Если таких ошибок много и они начинают создавать проблемы пользователям, то без модификации кода, удаления этих скобок очень трудно найти, где они произошли и почему. Описанное поведение системы позволяет говорить о том, что при возникновении ситуации, когда внутри транзакций нужно использовать скобки Попытка… Исклю-чение… КонецПопытки, необходимо, отработав исключительную ситуацию, вызывать оператор ВызватьИсключение. Случается, однако, что транзакция, встретившись с ошибкой, находящейся в скобках Попытка… Исключение… КонецПопытки, продолжает работу. Такое различие в поведении будет зависеть от типа исключительной ситуации. Исключительные 49 Теорияситуации бывают восстановимыми (после которых можно продолжить работу и завершить транзакцию) и невосстановимыми (после которых нельзя продолжить работу и завершить транзакцию, например, ошибка базы данных). Внешне это может выглядеть как зависимость от того, как код, вызвавший исключение, и скобки Попытка… Исключение… КонецПопытки расположены относительно ближайшей к ним транзакции. Пример 1НачатьТранзакцию();ПопыткаЭтотОбъект.ВыполнитьНесуществующийМетод();// (такого метода у объекта не создавали)ИсключениеКонецПопытки;Запрос = Новый Запрос;Запрос.Текст = “ВЫБРАТЬ| ПлатежноеПоручение.Ссылка|ИЗ| Документ.ПлатежноеПоручение КАК ПлатежноеПоручение”;Результат =Запрос.Выполнить();СпрСсылка =Справочники.Организации.НайтиПоКоду(“000001”);СпрОбъект =СпрСсылка.ПолучитьОбъект();СпрОбъект.НаименованиеПолное =ТекущаяДата();// это чтобы отследить, зафиксирована транзакция или нетСпрОбъект.Записать();ЗафиксироватьТранзакцию();Код выполнится. Транзакция успешно завершится. Исключительная ситуация оказа-лась расценена как восстановимая.Пример 2Сначала в процедуру ПриЗаписи модуля справочника Организации добавим строку: ЭтотОбъект.ВыполнитьНесуществующийМетод();// (такого метода у объекта не создавали)Далее изменим код из примера 1:НачатьТранзакцию();ПопыткаСпрСсылка =Справочники.Организации.НайтиПоКоду(“000001”);СпрОбъект =СпрСсылка.ПолучитьОбъект();СпрОбъект.НаименованиеПолное =ТекущаяДата();//это чтобы отследить, зафиксирована транзакция или нетСпрОбъект.Записать(); // неявная транзакция, там, как помним, ошибкаИсключениеКонецПопытки;Запрос = Новый Запрос;Запрос.Текст = “ВЫБРАТЬ50 Настольная книга 1С:Эксперта по технологическим вопросам| ПлатежноеПоручение.Ссылка|ИЗ| Документ.ПлатежноеПоручение КАК ПлатежноеПоручение”;Результат =Запрос.Выполнить();ЗафиксироватьТранзакцию();Получим ошибку: Ошибка при вызове метода контекста (Выполнить)Результат =Запрос.Выполнить();По причине: Ошибка выполнения запроса.По причине: В данной транзакции уже происходили ошибки!Исключительная ситуация, хотя она вызвана аналогичной строкой кода, потянула за собой дополнительные последствия (откат транзакции записи элемента справочника) и оказалась расценена как невосстановимая.3.7. Блокировки данных СУБД. Уровни блокировок.Совместимость блокировокБлокировка – это отметка (информация) о том, что требуемый ресурс в настоящее время захвачен (в случае блокировок в рассматриваемых информационных системах захвачен транзакцией).В СУБД на блокировках основана работа механизм обслуживания параллельных запросов.Возвращаясь к аналогии с поездкой в магазин, можем указать следующие аналоги блокировок: ■ покупатель у стеллажа с товаром: его самого видно, эта визуальная информация есть указание на блокировку ресурса «стеллаж»; ■ ряд стеллажей, перегороженный для работы погрузчика: сам погрузчик не зани-мает всего ряда, но ресурс «ряд стеллажей» заблокирован ограничительными лентами полностью; ■ автомобиль на шоссе: его видно, эта визуальная информация есть указание на блокировку ресурса «часть дорожного полотна»;13 ■ знак «ремонт» и ограждение: даже если за ними сейчас нет рабочих, это указание на блокировку ресурса «протяженный участок дороги».Еще раз обращаем внимание, что вообще-то блокировка – это не физический захват ресурса, а информация о том, что ресурс захвачен. В широко известной статье про яблоки18 для подчеркивания этого специально используется внесение записей о захвате ресурсов, потому что иначе, как и в приведенных выше примерах с блоки-рованием ряда стеллажей и протяженного участка дороги, невозможно объяснить и описать захват большего количества ресурсов, чем захватывается физически. 18 Эта статья является фрагментом книги: П. С. Белоусов, А. В. Островерх «1С:Предприятие: от 8.0 к 8.1». Дата выхода книги – ноябрь 2007.51 ТеорияИногда, конечно, можно приводить аналогии и с физическим захватом объектов, понимая под информацией о захвате непосредственное наблюдение факта захвата ресурса. Но вот если мы хотим разобрать работу самого механизма блокировок, физический захват от информации о нем надо отделять.Следует отметить, что блокировки с точки зрения прикладной логики могут быть необходимыми, а могут быть избыточными. Ограждение ремонта дороги, безусловно, необходимо. Но то же самое ограждение ремонта дороги, занимающее гораздо больше места, чем реально требуется для проведения работ (можно было оградить сначала один ряд, потом второй, а оградили оба на весь период ремонта), или продолжающее стоять после того, как работы закончены, являет собой хорошую иллюстрацию избыточных блокировок.Далее в этой главе мы рассмотрим то, что называют «блокировками СУБД». Эти блокировки устанавливает менеджер блокировок СУБД, и устанавливает он их только для транзакций. О блокировках, которые устанавливаются платформой «1С:Предприятие» (как объектных, так и транзакционных, устанавливаемых собственным менеджером транзакционных управляемых блокировок), см. главу «Теория», раздел 3.8. Переходя к разбору понятия уровня блокировок, нельзя не отметить путаницу в терминах и попытаться хотя бы слегка с ней разобраться. Разное применение одинаковых терминов приведено в таблице 3.7 .1. В данной работе мы будем придер-живаться первого столбца, кроме случаев, где об этом будет специально сказано.Таблица 3.7.1. Разное применение одинаковых терминов, касающихся блокировокТермин, применяемыйв «1С» сообществе Термин документации SQLServer Что это на самом делеУровень блокировок Режимы блокировок (Lock modes) Определяют доступ одновременных тран-закций к ресурсам (материал этой главы) Тип блокировокРежим блокировокРежим блокировок Нет Неаккуратное использование термина «Режим управления блокировкой данных» (автоматический или управляемый)Гранулярность блокировок Гранулярность блокировок (Lock granularity),также Уровень блокировок (Lock level) Объем (уровень в иерархии) ресурсов, на который накладывается блокировка (напр., запись или таблица). При неакку-ратном использовании термина «уровень блокировок» может теряться понимание, что на самом деле речь не об уровне блоки-ровки, а об уровне блокируемых ресурсов Вид блокировокУровень блокировок (напр. в выражении «блокировка на уровне записей») Нет Тип блокировок (Lock type) Элемент Visual Studio Team Foundation Server 2012В простейшем случае выделяют два уровня блокировок: исключительный (моно-польный) и разделяемый. Исключительный уровень не дает работать с ресурсом никому, кроме захватившей его транзакции, используется для отметки о том, что в ресурс осуществляется запись. Разделяемый уровень позволяет работать с ресурсом другим транзакциям, если они также готовы ограничиться только разде-ляемым уровнем блокировки. Этот уровень используется для отметки, что осущест-вляется чтение ресурса.52 Настольная книга 1С:Эксперта по технологическим вопросамНа практике, однако, этих двух уровней иногда оказывается мало, и для решения некоторых прикладных задач могут быть введены дополнительные уровни. В таблице 3.7.2 показаны уровни блокировки ресурсов, применяемые компонентом Database Engine SQL Server 2005. В этом случае названия уровней применяются разные, но они являются только синонимами, и при их использовании нет разно-чтений, поэтому они все приведены вместе.Таблица 3.7.2. Режимы блокировки ресурсов, применяемые SQL Server 2005Режим блокировки ОписаниеSharedРазделяемая, совмещаемая блокировка (S) Используется для операций считывания, которые не меняют и не обновляют данные, такие как инструкция SELECTUpdateБлокировка обновления (U) Применяется к тем ресурсам, которые могут быть обновлены. Предотвращает возникновение распространенной формы взаимоблокировки, возникающей тогда, когда несколько сеансов считывают, блокируют и затем, возможно, обновляют ресурсExclusiveЭксклюзивная, исключительная, монопольная блокировка (Х) Используется для операций модификации данных, таких как инструкции INSERT, UPDATE или DELETE. Гарантирует, что несколько обновлений не будет выполнено одновременно для одного ресурсаIntentБлокировка с намерением (IS, IX, SIX) Используется для создания иерархии блокировок. Типы намеренной блокировки: с намерением совмещаемого доступа (IS), с намерением монопольного доступа (IX), а также совмещаемая с намерением монопольного доступа (SIX). Блокировки с намерением называются так потому, что их получают до блокировок ресурсов более низкого уровня19, то есть они обозначают намерение поместить блокировку на более низком уровне ресурсов. Имеют особенность: устанавливаются на верхних уровнях иерархии (например, на уровне таблицы). Таким образом, если в графе взаимоблокировки встретилась блокировка с намерением, можно сразу говорить о том, что ею заблокирован большой объем данных, совершенно точно это не единичные записи________________19 В данном предложении под высоким/низким уровнем понимается не Lock mode, а именно Lock level – объем (уровень) данных, на который накладывается блокировка. Речь идет, например, о том, что при постановке какой-то блокировки на запись таблицы на всю таблицу ставится соответствующая блокировка намерения. Благодаря этому предотвращается изменение ресурса более высокого уровня другими транзакциям таким образом, что это сделает недействительной блокировку более низкого уровня. И нет необходимости проверять блокировки в каждой строке и на каждой странице, чтобы убедиться, что транзакция может заблокировать всю таблицу, что повышает производительность.53 ТеорияРежим блокировки ОписаниеSchemaБлокировка схемы (Sch-S, Sch-M) Используется во время выполнения операции, зависящей от схемы таблицы. Типы блокировки схем: блокировка изменения схемы (Sch-S) и блокировка стабильности схемы (Sch-M)Bulk UpdateБлокировка массового обновления (BU) Используется, если выполняется массовое копи-рование данных в таблицу и указана подсказка TABLOCKKey-rangeДиапазон ключей Защищает диапазон строк, считываемый запросом при использовании уровня изоляции транзакции Serializable. Запрещает другим тран-закциям вставлять строки, что помогает запросам такой транзакции уточнять, были ли запросы запущены повторноНа два режима блокировок SQL Server хотелось бы обратить особое внимание:1. Блокировка обновления. На практике включается добавлением в текст запроса на языке запросов «1С:Предприятия» опции ДЛЯ ИЗМЕНЕНИЯ. Имеет смысл только в транзакциях с уровнями изоляции Serializable и Repeatable Read, т. е. только для автоматического режима управления блокировкой данных, потому что в случае использования Read Committed, если данные запросом не изменя-лись, блокировка все равно снимается после выполнения запроса.2. Блокировка диапазона ключей. Используется только в транзакциях с уровнем изоляции Serializable. В системах «1С» такие транзакции используются только при автоматическом режиме управления блокировкой данных. Таким образом, если блокировка Key-range попала во взаимоблокировку, первый подходящий способ от этой взаимоблокировки избавиться – перейти в управляемый режим. Способность нескольких транзакций одновременно обзавестись блокировками на один и тот же ресурс определяется совместимостью блокировок. Если на ресурсе уже стоит блокировка от другой транзакции, новое требование на блокировку, полу-ченное от другой транзакции, может быть удовлетворено, только если затребованный уровень блокировки совместим с уже установленным уровнем. В противном случае транзакция, запросившая новую блокировку, будет ждать, пока не истечет время ожидания существующей блокировки. В таблице 3.7 .3 показана совместимость для наиболее распространенных уровней блокировки.Таблица 3.7.3. Совместимость наиболее распространенных уровней блокировки SQL ServerЗапрашиваемый уровень Уже предоставленный уровеньS U XРазделяемая (S) Да Да НетОбновления (U) Да Нет НетИсключительная (Х) Нет Нет Нет54 Настольная книга 1С:Эксперта по технологическим вопросам3.8. Сведения об управляемых и объектныхблокировкахВ платформе «1С:Предприятие» существуют два механизма, которые называются блокировками: ■ транзакционные блокировки, ■ объектные блокировки.Общего у них то, что они обе по сути обеспечивают внесение и контроль записей о том, что некие ресурсы заблокированы. Но и сами эти ресурсы, и ситуации, когда эти механизмы работают, различаются настолько, что эти два механизма надо рассма-тривать как совершенно разные и независимые, каковыми они на деле и являются.Транзакционные блокировки – это аналог блокировок СУБД, которые рассматри-вались в предыдущей главе. Они обеспечиваются менеджером транзакционных блокировок. Они используются, например, в дополнение к блокировкам СУБД, чтобы убирать побочные эффекты параллелизма, присущие уровню изоляции Read Committed, который устанавливается для СУБД при включении управляемого режима управления блокировкой данных в «1С» (это не единственное их назначение, в целом область применения управляемых блокировок намного шире).Транзакционные блокировки вместе с блокировками СУБД входят в сферу профес- сиональной деятельности 1С:Экспертов по технологическим вопросам. Конфликты этих блокировок – это такие же таймауты и взаимоблокировки. Как и конфликты блокировок СУБД, они обычно рассматриваются как критичные ошибки. Также и способ образования этих конфликтов соответствует способу их образования в СУБД.Напротив, объектные блокировки в эту сферу не входят20 , но, чтобы было понятно, о чем речь, сначала уделим внимание им. 14Механизм объектных блокировок позволяет оповестить пользователей о захвате объектных данных «1С:Предприятия»: справочников, документов, планов видов характеристик, планов счетов, планов видов расчета, бизнес-процессов, задач, планов обмена. То есть это не столько механизм защиты, сколько механизм опове-щения. Чаще всего пользователи видят сообщения от этого механизма, редактируя данные объектов в формах, и воспринимают их как ошибку (на самом деле если эти сообщения и можно считать сообщениями об ошибках, то только об ошибках организации работы пользователей): 1. «Не удалось заблокировать запись. Действие (изменение, удаление или блоки-ровка записи) не выполнено».20 События, происшедшие с момента выхода первого издания, показали, что и объектные блокировки могут являться предметом внимания 1С:Экспертов по технологическим вопросам, если имеет место неправильно организованная массовая работа с одними и теми же объектами. Например, массовый просмотр одних и тех же объектов через форму элемента не является ошибкой проектирования. А вот массовое закрытие этих форм кнопкой ОК, которая не только закрывает окно, но и перезаписывает объект, – это ошибка, и для форм, открывающихся только для целей просмотра, возможность записи тем или иным способом надо закрывать.55 Теория2. «Операция не может быть выполнена из-за несоответствия версии или отсут-ствия записи базы данных (возможно, запись была изменена или удалена)». Либо в последних версиях: «Данные были изменены или удалены другим пользова-телем».Если один пользователь начинает модификацию объекта в форме, а другой после этого тоже попытается начать редактирование того же объекта, то понятно, что одно-временное редактирование одного и того же объекта приведет к нежелательным последствиям. Поэтому расширение формы устанавливает пессимистическую блокировку, не позволяющую редактировать кем-то уже редактируемые данные. И как только второй пользователь попытается этот объект модифицировать, он получит сообщение 1.Если теперь первый пользователь запишет изменения и закроет форму, то песси-мистическая блокировка снимется. Но если другой пользователь опять попытается начать редактирование того же объекта в той же открытой ранее форме, он получит сообщение 2 – сработает оптимистическая блокировка, не позволяющая редактиро-вать данные, измененные или удаленные за время, прошедшее с их считывания.Названия «пессимистическая» и «оптимистическая» взялись из следующего: ■ пессимистическая блокировка исходит из предположения, что «если что-то плохое может случиться, это обязательно случится», то есть если мы выполняем действие, конкурентное выполнение которого может привести к «поломке» данных, то правильным будет исключить возможность конкурентного исполнения; ■ оптимистическая блокировка предполагает, что во время обновления записи в базе мы будем единственными, кто ее меняет. В большинстве случаев так оно и есть (оптимизм оправдан). Но перед этим необходимо точно удостовериться, что запись с момента ее чтения не изменилась. Объектные блокировки снимаются при выгрузке объекта из памяти (например, при закрытии формы или в конце процедуры). Со стартом и окончанием транзакций это не связано никак21 . 15Механизм транзакционных управляемых блокировок «1С» (механизм управ-ляемых блокировок), как уже говорилось, обеспечивается своим собственнымменеджером и решает вопросы, аналогичные вопросам менеджера блокировокСУБД. Точнее говоря, этот механизм позволяет при необходимости усилить изоли-рованность транзакций, не меняя уровня изоляции в СУБД. И понятно, почему нетсмысла его использовать в автоматическом режиме управления блокировками: тамуровень изоляции для СУБД и так самый высокий –Serializable.Заметим, что данных механизма объектных блокировок этот механизм при работене видит и не принимает в расчет вообще.21 Кроме того, пессимистическая объектная блокировка может быть установлена программно методом <Объект>.Заблокировать() и снята методом <Объект>.Разблокировать(). Эти методы есть у объектных типов данных. Важно: не следует путать методы <Объект>.Заблокировать() и <БлокировкаДанных>.Заблокировать(). Первый устанавливает объектную пессимистическую блокировку, второй – транзакционную управляемую.56 Настольная книга 1С:Эксперта по технологическим вопросамКак в простейшем случае для СУБД, для управляемых блокировок «1С» выде-ляют два уровня: исключительный и разделяемый. Их описание, приведенное в синтакс-помощнике, отражено в таблице 3.8.1.Таблица 3.8.1. Уровни блокировки ресурсов управляемыми блокировками «1С»Уровень блокировки(РежимБлокировкиДанных) ОписаниеРазделяемый (Shared) Разделяемая блокировка позволит конкурирующему процессу установить разделяемую блокировку по этому же условию, но не позволит установить исключительную блокировкуИсключительный (Exclusive) Исключительная блокировка не позволит конкурирующему процессу установить разделяемую или исключительную блокировку по этому же условиюСовместимость уровней блокировок, приведенная в таблице 3.8.2, классическая.Таблица 3.8.2. Совместимость уровней управляемых блокировок «1С»Запрашиваемый уровень Уже предоставленный уровеньS XРазделяемая (S) Да НетИсключительная (Х) Нет НетУстановленные управляемые блокировки, как разделяемые, так и исключительные, держатся до конца транзакции22 . 16Менеджер транзакционных управляемых блокировок «1С» ничего не знает и никак не взаимодействует с механизмом транзакционных блокировок СУБД. Это означает, например, что ресурсы, заблокированные исключительными управляемыми блоки-ровками, могут оставаться доступными для чтения запросами на языке запросов. Это может помочь обходить некоторые неразрешимые конфликты управляемых блокировок (взаимоблокировки), но при таком способе обхода есть опасность, что возникнут побочные эффекты параллелизма, и это надо просчитывать.Аналогично в обратную сторону: управляемые блокировки «1С» могут быть уста-новлены независимо от того, какие ресурсы заблокированы блокировками СУБД.Такую рассогласованность не всегда можно игнорировать. Поэтому при выполнении некоторых операций с базой данных платформа может ставить управляемые блоки-ровки самостоятельно.Управляемые разделяемые блокировки устанавливаются платформой при чтении в объектной технике23 следующих видов объектов: 17 ■ набор записей регистра сведений, ■ набор записей регистра накопления, ■ набор записей регистра бухгалтерии, 22 Самые глубокие извинения от автора всем читателям за ошибку в этом месте в первом издании книги. Пример из первого издания, содержавший ошибочный анализ, см. в разделе 4.25 «Работа с ТЖ. Как расследовать конфликт на управляемых блокировках». 23 Чтение в объектной технике обладает еще одной особенностью: оно в ряде случаев выполняется в неявной транзакции. Подробнее см. раздел 3.15.57 Теория ■ набор записей регистра расчета, ■ набор записей перерасчета, ■ набор записей последовательности.При записи в объектной технике указанных выше видов объектов устанавливаются исключительные управляемые блокировки. Платформа НЕ устанавливает блокировок при чтении в объектной технике как минимум следующих объектов: ■ констант и наборов констант; ■ справочников (например, используя методы Справочники.ИмяСправочника.Выб-рать(), СправочникВыборка.Следующий(), СправочникВыборка.ПолучитьОбъект(), СправочникСсылка.ПолучитьОбъект() и т. д.); ■ документов (аналогично справочникам); ■ других объектов (планов видов характеристик, планов счетов и т. д.) . Методика получения точной информации, какие именно управляемые блокировки установлены в каждом конкретном случае, описана в разделе 4.24 «Работа с ТЖ. Как посмотреть, какие управляемые блокировки были установлены».Методика расследования конфликтов на управляемых блокировках описана в разделе 4.25 «Работа с ТЖ. Как расследовать конфликт на управляемых блоки-ровках».В заключение расскажем еще раз о режимах управления блокировкой данных. Если требуется обеспечить должное качество работы информационной системы «1С» с высокими требованиями к параллельной работе пользователей, то использование автоматического режима управления блокировкой данных является ошибкой, без устранения которой другие работы по оптимизации системы могут не иметь смысла.При этом использование смешанного, «автоматического и управляемого» режима в таких случаях также чаще всего будет ошибкой, поскольку, как правило, основные прикладные объекты в таком переходном состоянии остаются с установленным автоматическим режимом управления блокировкой.3.9. Ошибки блокировок:таймауты и взаимоблокировкиОбщие вопросыЕсли транзакция хочет установить блокировку на ресурс, но обнаруживает, что на ресурсе уже стоит несовместимая с ней блокировка, она ставится в очередь на установку блокировки.При наступлении определенных событий транзакция может быть удалена из очереди до того, как она дождется своего права установить блокировку. Если такое проис-ходит, это приводит к возникновению исключительной ситуации, которая называется ошибкой (конфликтом) блокировок. Транзакция при этом откатывается, пользователь получает сообщение об ошибке.58 Настольная книга 1С:Эксперта по технологическим вопросамТекст сообщения об ошибке зависит от того, был ли это конфликт управляемых блокировок или конфликт блокировок СУБД. Если конфликт произошел в СУБД, текст зависит от того, что это за СУБД, а также от ее версии и языка. Ключевые фразы, по которым на текущий момент можно определить текст ошибок блоки-ровок, приведены в таблице 3.9.1. Причин такого удаления две:1. Транзакция стоит в очереди с точки зрения системы уже слишком долго, не выполняя действий и, возможно, блокируя ресурсы, которые ей требовались на предыдущих шагах. Такая причина называется таймаутом, ошибкой превы-шения времени ожидания на блокировке.2. Произошла ситуация, которая была квалифицирована как взаимная блокировка ресурсов (deadlock, взаимоблокировка). Таблица 3.9.1. Подстроки, идентифицирующие ошибки блокировок в текстах сообщенийоб ошибках (пользователям и в технологическом журнале «1С»)Подстрока ОшибкаПревышено максимальное время ожидания таймаут на управляемых блокировках (1С- рус.)Maximum idle time for lock access таймаут на управляемых блокировках (1С-англ.)Неразрешимый конфликт блокировок взаимоблокировка на управляемых блоки-ровках (1С-рус.)Unresolved lock conflict in a session взаимоблокировка на управляемых блоки-ровках (1С-англ.)SQL Server: Lock request time out period exceeded таймаут СУБД SQL Server (англ.)SQL Server: Превышено время ожидания запроса на блокировку таймаут СУБД SQL Server (рус.)was deadlocked on lock resources with another process and has been chosen as the deadlock victim взаимоблокировка СУБД SQL Server (англ.)вызвала взаимоблокировку ресурсов взаимоблокировка СУБД SQL Server (рус.)SQL0911N The current transaction has been rolled back because of a deadlock or timeout любой конфликт блокировок СУБД IBM DB2 (англ.)SQL0911N Из-за тупиковой ситуации или из-за истечения срока любой конфликт блокировок СУБД IBM DB2 (рус.)ORA-00051: timeout occurred while waiting for a resource таймаут СУБД Oracle Database (англ.)ORA-00051: Истекло время ожидания ресурса таймаут СУБД Oracle Database (рус.)ORA-00060: deadlock detected while waiting for resourceилиORA-00060: Deadlock detected взаимоблокировка СУБД Oracle Database (англ.)ORA-00060: Возникла мертвая блокировка во время ожидания ресурса илиORA-00060: тупик обнаружено взаимоблокировка СУБД Oracle Database (рус.)Рассмотрим каждую из ошибок подробнее.59 ТеорияТаймаутВремя, которое транзакция может ждать освобождения ресурса, задается в свойствах системы. В системах на платформе «1С:Предприятие» оно по умолчанию равно 20 секундам и устанавливается в конфигураторе (Администрирование –Параметрыинформационной базы –Время ожидания блокировки данных (в секундах)). Это время действует и на управляемые блокировки «1С:Предприятия», и на блокировки СУБД. Если транзакции приходится ждать дольше, возникает таймаут. Казалось бы, ждать, так ждать, и первый приходящий в голову способ решить проблему – ускорить время обработки каждой транзакции, например, повысив харак-теристики оборудования или оптимизировав код с точки зрения его выполнения. Однако существуют дополнительные факторы, которые надо учитывать и которые в ряде случаев могут оказаться существенно более важными.Рассмотрим ситуации, происходящие в офисе, в котором работают две сотрудницы: Светочка и Леночка. Они приходят на работу примерно в одно время, а уходят ровно в 18:00, если нет начатой, но недоделанной работы. Они дружат, то есть у них существует договоренность, что документ24 , лежащий на общем столе, читать можно, а документ, переложенный на личный стол или находящийся в руках, другой сотруднице трогать и смотреть нельзя25 . 18191. Обеим сотрудницам за сегодня нужно внести изменения в один и тот же доку-мент. Леночка пришла чуть позже, и Светочка уже взяла документ и начала вносить в него изменения. Она не отдаст документ, пока не сделает свою работу с ним до конца (Светочка установила необходимую исключительную блоки-ровку). Успеет ли Леночка до 18:00 начать вносить свои изменения в документ или уйдет домой, даже не начав работу, зависит от следующего: □ скорости работы Светочки; □ объема документа; □ объема вносимых изменений; □ не вызовут ли Светочку посередине дня на неопределенное время на сове-щание, а документ она унесет с собой – вызов модального окна из тран-закции; □ не потребуется ли для внесения изменений в этот документ много раз бегать к шкафу за дополнительной информацией – запрос в цикле; □ не потребует ли внесение изменений в этот документ поездки в другой офис за дополнительной информацией – получение в транзакции данных из внеш-него источника; □ не потребует ли внесение изменений в этот документ вносить изменения в другие документы, за которыми придется бегать в лучшем случае в соседнюю комнату, а в худшем – в соседнее здание – вложенные тран-закции. Но там другие документы могут оказаться еще и заняты другими 24 В данном случае понятию «документ» в тексте больше соответствует понятие «набор записей регистра» в терминах метаданных «1С», а не «документ». 25 Блокировка – это не факт захвата ресурса, а запись о таком захвате. Но здесь в примерах для простоты будем считать, что факт захвата является и информацией о нем.60 Настольная книга 1С:Эксперта по технологическим вопросамсотрудницами, так что Светочке придется ждать, пока они освободят их. Все документы с внесенными изменениями Светочка будет хранить у себя, пока не закончит работу с основным документом.Как видим, начнет ли Леночка сегодня работу, зависит не только от Светочки и от объема вносимых изменений, но и от Светочкиной должностной инструкции. Но и этим дело не ограничивается.2. На следующий день обеим сотрудницам нужно внести изменения в разные документы: Светочке – в новый, а Леночке – в не начатый вчера. Но доку-менты лежали в одной стопке, Леночка опять пришла чуть позже, и Светочка уже взяла всю стопку документов и начала вносить изменения в свой документ, пропустив Леночкины, но и не отдавая его (Светочка установила избыточнуюисключительную блокировку). □ Все, из-за чего Леночка ждала в предыдущий день, повторяется снова. Трагизм ситуации усиливается тем, что ее документ Светочке уже не нужен, но по правилам она не отдаст всю взятую стопку документов, пока не закончит с ней работать.Как видим, начнет ли Леночка сегодня работу, зависит не только от Светочки, от объема вносимых изменений и должностной инструкции Светочки, а в случае возможности избыточных блокировок еще и от того, не взяла ли Светочка не свой документ. Но и этим дело не ограничивается.3. На следующий день обеим сотрудницам нужно опять внести изменения в разные документы: Светочке – в новый, Леночке – в не начатые вчера и поза-вчера. Леночка решила, что теперь она возьмет себе всю стопку, но опять пришла чуть позже, и Светочка уже взяла один свой документ и начала с ним работать. Поскольку Леночка твердо решила брать стопку целиком (собирается устано-вить избыточную исключительную блокировку), ей опять приходится ждать.Как видим, начнет ли Леночка сегодня работу, зависит не только от Светочки, от объема вносимых изменений, Светочкиной должностной инструкции, не взяла ли Светочка не свой документ, а еще и от того, не собирается ли Леночка взять не свои документы. Но и этим дело не ограничивается.4. У Светочки и Леночки есть начальник, который должен проверять за ними все измененные ими документы. Но поскольку документы приходят к нему только от Светочки, он и выполняет только половину работы (характерный спадзагрузки после «бутылочного горлышка»).Переходя от примеров к теории, причинами таймаутов могут являться: ■ неправильная организация рабочего процесса (конкуренция за одни и те же данные); ■ выбор неправильного прикладного объекта метаданных конфигурации для хранения данных (тоже конкуренция за одни и те же данные, см. раздел 3.11); ■ игнорирование особенностей работы ресурсов, в которые возможна только после-довательная запись, см. раздел 3.11; ■ неоптимальная работа запросов, как вызывающая избыточные блокировки, так и увеличивающая время выполнения самих этих запросов;61 Теория ■ использование механизмов, провоцирующих неоптимальную работу запросов; ■ использование высокого уровня изоляции транзакций; ■ включение в транзакцию механизмов, вызывающих непрогнозируемое увели-чение ее времени и ставящих ее в зависимость от посторонних ресурсов (модальные окна, работа с внешними источниками, вложенные транзакции); ■ увеличение времени транзакции, как за счет медленной работы кода, так и за счет объединения нескольких транзакций в одну (например, групповая обработка документов в одной транзакции).В качестве причин таймаутов иногда называется недостаточная производительность оборудования. Но надо понимать, что эта причина может явиться руководством к действиям по улучшению оборудования практически в единственном случае: когда оборудование явно не соответствует стоящим перед ним задачам, и показатели его загрузки при работе существенно превышают все рекомендованные значения. В подавляющем же большинстве ситуаций при проблемах параллельности оборудо- вание сервера СУБД бывает недогружено, и рекомендации будут прямо противопо-ложны: ■ делать апгрейд оборудования при проблемах параллельности – плохая идея; ■ ускорение оборудования, скажем, на 30 % приведет к уменьшению времени ожидания в очереди на те же 30 %. А устранение очереди (распараллеливание работы) ускорит процесс в N раз, где N – количество участников очереди. То есть эффект несопоставимый.Чтобы бороться с таймаутами, нужно выяснить, какая из перечисленных выше причин привела в данном случае к таймаутам, и либо устранить эту причину, либо перевести ее в приемлемые рамки.Надо иметь в виду, что, убрав избыточные блокировки (и избавившись от тайма-утов), мы увеличиваем параллельность работы и как следствие можем увеличить загрузку оборудования. То есть если раньше оборудование справлялось, то теперь могут возникнуть проблемы. Взаимоблокировка (deadlock)Взаимоблокировка возникает, когда две или более транзакции ждут друг друга из-за того, что каждая из сторон блокирует ресурс, необходимый другой стороне.Иначе говоря, сущность взаимоблокировок в следующем: Светочка ждет Леночку, а Леночка ждет Светочку. Замкнутый круг. Решается только принудительным внешним воздействием.В СУБД это воздействие происходит так: при обнаружении взаимоблокировки монитор блокировок назначает жертву, производит откат ее транзакции и возвращает приложению ошибку. Остальные транзакции имеют возможность успешно завер-шиться.62 Настольная книга 1С:Эксперта по технологическим вопросамВозникновение взаимоблокировок сводят к следующим ситуациям.1. Захват ресурсов в разном порядке. X1 -> X2, X2-> X1.Светочке сказали: распишись сначала в договоре, потом в приложении и потом отдай оба листа. Леночке сказали несколько иначе: распишись сначала в приложении, потом в договоре и потом отдай оба листа.Если девушки будут работать по очереди, ничего страшного не произойдет. Если же они начнут работать одновременно, то ни одна из них не сможет завершить задачу: им не сказано «отдавать один лист», сказано – «отдать оба»26 . 20В такой постановке это в чистом виде ошибка организации работы. Исправляется она организацией доступа к ресурсам в одинаковом порядке. Переходя к «1С», если есть такие подозрения, порядок доступа можно проверить (без использования ЦУП), например, через подписку на событие ПриЗаписи наборов записей всех регистров, тем или иным образом выводя сообщения об имени регистра, в который идет запись, и сравнивая последовательно записанные протоколы для разных типов документов.Особый случай этой же ситуации: чтение общей области после раздельной записи. X1 -> S12, X2 ->S12.Светочке сказали: распишись в договоре, потом прочитай и отдай оба листа. Леночке сказали: распишись в приложении, потом прочитай и отдай оба листа.Леночка и Светочка изменяют разные документы. Но потом им требуются ресурсы друг друга, как правило, объединенные вместе.В системах на платформе «1С:Предприятие» эти взаимоблокировки стали часто возникать после появления технологии разделения итогов, и происходит это чаще всего в двух случаях: □ Проведение документа, контроль остатков после записи движений. Если разделение итогов включено, то запись движений осуществляется с учетом сплиттера (разделителя итогов, не путать с разделителем данных), и поэтому может производиться параллельно, даже при полностью совпадающих значе- ниях периода, счета и измерений (рассматриваем регистр бухгалтерии). Но при контроле остатков сплиттер смысла не имеет, то есть считываются все итоги по данным значениям периода, счета и измерений. И получаем ту самую взаимоблокировку, описанную в примере. □ Перепроведение документа, контроль остатков или другое чтение (расчет себестоимости списания) до записи движений или после него, не важно. Если разделение итогов включено, то запись движений при их удалении осущест-вляется с учетом сплиттера. Дальнейшее чтение приводит к взаимоблоки-ровке.26 Отличие работы СУБД от этого и следующих примеров состоит в том, что в СУБД транзакция, назначенная жертвой, откатывается, то есть девушке пришлось бы стереть свои изменения или подпись. 63 ТеорияВ этом случае с взаимоблокировкой надо бороться с помощью свойства БлокироватьДляИзменения, которое есть у наборов записей регистров бухгалтерии и регистров накопления. Пример использования:Движения.Хозрасчетный.БлокироватьДляИзменения =Истина;Движения.Хозрасчетный.Записать();Согласно синтакс-помощнику установка этого свойства в Истину: «Устанавливает режим, при котором в процессе записи набора будет установлена управляемая блокировка для всех комбинаций измерений в соответствии с записями набора записей. Имеет смысл использовать, если проверка итогов регистра выполняется после записи и заблокировать нужно именно те комбинации, по которым записываются записи. В этом случае можно не использовать объект БлокировкаДанных».Особо обращаем внимание на то, что технически работа свойства БлокироватьДляИзменения реализована с помощью установки управляемой блокировки. В автоматическом режиме управления блокировками попытка использования БлокироватьДляИзменения не игнорируется (в отличие от ДЛЯ ИЗМЕНЕНИЯ в управляемом режиме), а приводит к исключительной ситуации. При этом разделитель итогов на уровне СУБД работает, т. е. возможна параллельная запись совпадающих наборов.Но дальше, если на самом деле имеет место высокая конкуренция за одни и те же данные (неправильная организация рабочего процесса или выбор неправильного прикладного объекта метаданных конфигурации для хранения данных), взаимоблокировка, вполне вероятно, превратится в таймаут. Однако на этом все не заканчивается.На другой день Светочка и Леночка изменяют каждая только свои документы. И каждая из них хочет принести начальнику на проверку всю стопку (обесобираются установить избыточную блокировку –не важно, исключительнуюили разделяемую). Такая взаимоблокировка может быть вызвана неоптимальной работой запроса на чтение. Неоптимальная работа запроса может быть вызвана как методическими ошибками, допущенными при его написании, так и спровоцирована, например, использованием механизмов, приводящих к появлению неоптимальных запросов, даже если сам запрос написан без явных ошибок (см. в этой главе ниже). 2. Повышение уровня блокировки ресурса. S1 -> X1, S1-> X1.Светочка подошла к столу и начала читать документ. Сразу за этим к столу подошла Леночка и начала читать тот же документ. Светочка увидела, что ей надо внести в этот документ изменения, и хотела было его унести к себе, но Леночка ей не дала: она еще его не дочитала. А затем и Леночка увидела, что ей тоже надо внести в этот документ изменения, и тоже хотела было его унести к себе, но теперь уже Светочка не дала ей этого сделать.Эта ситуация, когда один и тот же ресурс блокируется сначала разделяемой блокировкой, а затем исключительной, и при параллельном обращении к этому ресурсу возникает взаимоблокировка, характерна для режима автоматического 64 Настольная книга 1С:Эксперта по технологическим вопросамуправления блокировками «1С». В этом режиме используются уровни изоляции транзакции Serializable и Repeatable Read, и разделяемые блокировки не снимаются после чтения, а остаются до конца транзакции. Но и в управляемом режиме можно получить тот же эффект, поставив явную разделяемую блокировку на данные, на которые затем явно или неявно будет установлена исключительная блокировка.Для обхода этой взаимоблокировки в SQL Server был введен особый уровень блокировки: U (Update), см. раздел 3.7 . Этот уровень совместим только с разделяемыми блокировками S, но сам с собой уже нет. Чтобы его задействовать, в запрос на языке запросов «1С» необходимо добавить опцию ДЛЯ ИЗМЕНЕНИЯ, при этом не забыв указать, какие таблицы блокировать, иначе запрос поставит эту блокировку на все таблицы, задействованные в нем.Если такая взаимоблокировка возникла на блокировках «1С», то перед чтением данных ресурса, в который потом будет идти запись, нужно ставить исключительную блокировку. Если разделяемая блокировка ставится явно и чтение производится на языке запросов, а не через объектную модель, нужно заменить ее сразу на исключительную блокировку.Для устранения взаимоблокировок нужно придерживаться следующих правил: □ осуществлять запись ресурсов в одинаковом порядке; □ избегать чтения ресурса после его записи, если включен режим разделения итогов; либо, если этого нельзя избежать, на время записи устанавливать свойство БлокироватьДляИзменения в Истину; □ в режиме автоматического управления блокировками «1С» в запросах вклю-чать опцию ДЛЯ ИЗМЕНЕНИЯ на те ресурсы, которые будут потом записаны; □ если есть необходимость поставить управляемую блокировку «1С» перед чтением данных ресурса, в который потом будет идти запись, нужно ставить не разделяемую блокировку, а исключительную.Далее, как и в случаях борьбы с таймаутами, помогает следующее: □ правильная организация рабочего процесса (снижение конкуренции за одни и те же данные организационными мероприятиями); □ выбор более подходящего прикладного объекта метаданных конфигурации для хранения данных (см. раздел 3.11); □ правильная организация работы ресурсов, в которые возможна только после-довательная запись, см. раздел 3.11; □ оптимизация запросов, ликвидация избыточных блокировок и уменьшение времени выполнения самих этих запросов; □ отказ от использования механизмов, провоцирующих неоптимальную работу запросов: это механизм разделения доступа на уровне записей при работе пользователя с ограниченными правами и механизм разделения данных при работе пользователя с незаданным общим реквизитом, если указано исполь-зование разделяемых данных «Независимо и совместно»;65 Теория □ снижение уровня изоляции транзакций (т. е. переход с режима автоматического управления блокировками «1С» на управляемый). Это, с одной стороны, уменьшит блокирование избыточных данных (снимется защита диапазона ключей), а с другой стороны, уменьшит время блокировки части ресурсов, т. к. все разделяемые блокировки будут сняты после выполнения запроса; □ использование Read Committed Snapshot (при работе с SQL Server переход на платформу 8.3 без режима совместимости с 8.2). Разделяемые блокировки на уровне СУБД не будут ставиться вовсе; □ отказ от включения в транзакцию механизмов, вызывающих непрогнозиру-емое увеличение ее времени и ставящих ее в зависимость от посторонних ресурсов (модальные окна, работа с внешними источниками, вложенные транзакции); □ отказ от ошибочного рекурсивного вызова ЭтотОбъект.Записать() из тран-закции записи этого же объекта. Платформа распознает такую ситуацию и не дает развиваться рекурсии, но ошибки блокировок при этом возникать могут; □ снижение времени транзакции, как за счет оптимизации работы кода, так и за счет объединения нескольких транзакций в одну (например, групповая обработка документов в одной транзакции); □ повышение производительности оборудования позволяет снизить вероят-ность взаимоблокировок, при этом, однако, не устраняя их причин.К сожалению, все это не гарантирует, что взаимоблокировок не будет. Нет методики, которая даст 100 % гарантию их отсутствия. Поэтому нужно уметь расследовать и устранять взаимоблокировки.В заключение еще об одном виде взаимоблокировок. Они могут возникать в СУБД Microsoft SQL Server и характеризуются следующими сообщениями об ошибке: ■ “Intra-query parallelism caused your server command (process ID #XX) to deadlock. Rerun the query without intra-query parallelism by using the query hint option (maxdop 1)”; ■ “Transaction (Process ID #XX) was deadlocked on thread communication buffer resources with another process and has been chosen as the deadlock victim”.Причиной является то, что при работе на многопроцессорном компьютере Microsoft SQL Server может попытаться распараллелить процесс выполнения запроса на несколько процессоров. Обычно это происходит в том случае, если план запроса неоптимален. При параллельном выполнении нескольких частей одного запроса на разных процессорах возможна взаимоблокировка.Для решения проблемы необходимо установить значение параметра max degree of parallelism («Максимальная степень параллелизма») равным 1 – SQL Management studio, свойства SQL server, закладка Дополнительно.Другим способом решения проблемы является оптимизация исполняемого запроса.Взаимоблокировки имеют характерную особенность поведения: при высокой интен-сивности работы они появляются большими группами – по пять-шесть штук подряд. Это связано с тем, что, когда две транзакции зацепились, об них спотыкаются еще несколько, и образуется куча-мала. Значимость ЦУП для расследования подобных ситуаций переоценить сложно.66 Настольная книга 1С:Эксперта по технологическим вопросам3.10. Эскалация блокировокЭскалация (укрупнение) блокировок – это повышение гранулярности блокировки (lock granularity, в некоторых источниках – lock level, «уровень блокируемых данных»). Это процесс преобразования многих мелкогранулированных блокировок в меньшее число крупногранулированных блокировок при вероятном увеличении конкуренции параллелизма.Гранулярность – это объем (уровень в иерархии) ресурсов, на который накладыва-ется блокировка. Упрощенно можно считать, что существуют следующие ресурсы, которые могут блокироваться СУБД27: 21 ■ строка: используется в управляемом режиме управления блокировками; ■ ключ: блокировка строки в индексе, используемая для защиты диапазонов значений ключа в транзакциях с уровнем изоляции Serializable, используется в автоматическом режиме управления блокировками при работе с регистрами; ■ страница; ■ таблица; ■ база (монопольный режим).Не важно, блокировались данные на уровне записей (строк), на уровне диапазона ключа или на уровне страницы. После эскалации они окажутся заблокированы на уровне таблицы, т. е. эскалация всегда происходит до уровня таблицы.Эскалация происходит, когда система решает, что заблокировать сразу более высокий уровень данных дешевле, чем продолжать набирать большое количество блокировок на нижнем уровне.Эскалация определяется, например, по наличию в трассировке профайлера SQL Server события Lock:Escalation (в стандартном шаблоне трассировки этого события нет, и его надо добавлять, а находится оно в группе событий Locks), см. главу «Инструкции», раздел 4.15.Перевод блокировки данных на уровень таблицы не позволит другим транзакциям параллельно работать с теми же данными. Она почти всегда избыточна, и это может привести к конфликтам блокировок, поэтому надо понимать, при каких условиях возникает эскалация.Эксперименты показывали, что в SQL server с установками по умолчанию эска-лация блокировки начиналась примерно при 3 400–4 800 записях в наборе непе-риодического независимого регистра сведений (точное значение не установлено). В IBM DB2 9.7 она начиналась ровно при 20 000 записях. Платформа «1С:Пред-приятие» до версии 8.3 производила эскалацию, также начиная с 20 000 записей, а в версии 8.3, по данным с ИТС, она начинается со 100 000 записей в наборе.27 Эскалации бывают на СУБД и в менеджере управляемых блокировок. Их поведение различно. Различие состоит в том, что если в момент попытки эскалации на СУБД MS SQL кто-то другой будет держать блокировку, то эскалации не произойдет, но при этом транзакция дальше продолжит свое выполнение. Если в «1С» кто-то другой будет держать блокировку, то «эскалирующаяся» транзакция попадет в ожидание от всех, кто еще держит блокировки на этом ресурсе. Если в «1С» не получится проэскалироваться в течение N (по умолчанию 20) секунд, то транзакция получит таймаут.67 ТеорияМомент, когда это происходит, в SQL server регулируется значением параметра Locks («Блокировки») – SQL Management studio, свойства SQL server, закладка Дополни-тельно – и зависит от доступной памяти. Также эскалация SQL server может быть отключена. Если отключать ее, то глобально28 , с помощью флага трассировки SQL 1211, например, выполнив следующий SQL запрос:22DBCC TRACEON (1211, -1)Но если ее отключить, то накладные расходы останутся бесконтрольными, и значи-тельная часть вычислительной мощности, возможно, будет расходоваться непроизво-дительно. Это может привести к очень заметному замедлению записи. Наличие технической возможности по отключению эскалацию отнюдь не означает, что этим надо пользоваться. СУБД делает эскалацию не от хорошей жизни. Это жест отчаянья. СУБД видит, что пользователи открыли огромные транзакции, и сама она тратит очень много ресурсов. Проблема не в СУБД, а в том, что транзакции захва-тывают слишком много ресурсов. Лечить надо именно это, а не отключать эскалации. В идеале транзакция должна быть крайне компактной – работать быстро, данных захватывать мало. Транзакция, которая длится 3 секунды, – это уже подозрительно. Транзакция на 10 секунд просто не должна иметь права на существование.Включить эскалацию обратно можно, деактивировав флажок 1211:DBCC TRACEОFF (1211, -1)На практике можно считать, что при использовании MS SQL Server документ «1С», имеющий свыше 1 000 строк в табличной части либо делающий свыше 1 000 движений по одному регистру, теоретически может при своем проведении вызывать эскалацию блокировок, поэтому при прочих равных условиях наличие больших документов – это потенциальная проблема параллельности работы. Это не значит, что такие документы нельзя провести. Просто нужно делать это не средствами платформы, а своим кодом – в нескольких относительно небольших транзакциях, обеспечив неделимость (атомарность) операции внешними средствами. 28 Если активация флага трассировки выполняется глобально на рабочем сервере, то выполнять DBCC TRACEON (trace# [, ….n],-1), чтобы избежать непредсказуемых последствий, рекомендуется только тогда, когда пользователи не выполняют запросов к серверу (фактически когда никто не работает). На рабочем сервере надежнее эти флаги включать, используя в командной строке параметр -T при запуске файла Sqlservr.exe. 68 Настольная книга 1С:Эксперта по технологическим вопросам3.11. Сведения о параллельности операцийс данными разных типовОбщие сведенияСистема позволяет осуществлять параллельное чтение и параллельную запись данных. Разные типы данных имеют разные возможности и ограничения по парал-лельному выполнению операций чтения и записи с ними.Сразу скажем, что поскольку данные, относящиеся в информационной базе «1С» к разным прикладным объектам конфигурации, хранятся в разных таблицах (как именно организовано хранение, будет рассказано в следующей главе), будем считать, что такие записи могут быть прочитаны и записаны параллельно всегда.Операция чтения в транзакции сложностей также не вызывает: даже при уровне изоляции транзакции Serializable при чтении устанавливается разделяемая блоки-ровка, а потому даже совпадающие записи одной таблицы могут быть прочитаны параллельно.К сложным ситуациям, когда в одной транзакции выполняются чтение и запись и когда в одной транзакции осуществляется запись в несколько разных прикладных объектов конфигурации, вернемся позднее. А сейчас разберем возможность только записи данных, относящихся к одному прикладному объекту (см. таблицу 3.11.1).Таблица 3.11.1. Сводные данные о параллельностиПрикладной объект конфигурации Возможности параллельной работыКонстанты в версиях до 8.2 .14, а также после – при использовании режимов совместимости «8.2 .13» и «8.1» Только по следовательно, притом даже разные константыКонстанты после 8.2 .14 (без использования режима совместимости) Одну и ту же константу – только после-довательно, но разные константы можно записывать параллельноВыгрузка сообщений обмена Выгрузка изменений, которые зарегистриро-ваны для прикладного объекта метаданных (например, справочника «Номенклатура»), и запись данных такого типа НЕ могут происходить параллельноНабор записей регистра расчета с использованием фактического периода действия Возможна параллельная запись, если отлича-ется период действия (месяц) или измерение, у которого стоит признак «базовое». Уточ- нение по данному вопро су см. нижеГраница регистрации последовательности Возможна параллельная запись, если отли-чается хотя бы одно измерение. На практике, однако, измерение, как правило, у всех совпадает («Организация»)Набор записей регистра сведений (независимый непериодический) Возможна параллельная запись, если отлича-ется хотя бы одно измерениеНабор записей регистра накопления (остатков), если разделение итогов выключено и используются текущие итоги Возможна параллельная запись, если отлича-ется хотя бы одно измерение, уточнение про период см. нижеНабор записей регистра бухгалтерии, если разделение итогов выключено и используются текущие итоги Возможна параллельная запись, если отличается счет или хотя бы одно измерение, уточнение про период см. нижеНабор записей регистра сведений (независимый периодический) Возможна параллельная запись, если отличается период (месяц) или хотя бы одно измерение69 ТеорияПрикладной объект конфигурации Возможности параллельной работыНабор записей регистра накопления (остатков), если разделение итогов выключено, а текущие итоги не используются Возможна параллельная запись, если отлича-ется хотя бы одно измерение, уточнение про период см. нижеНабор записей регистра бухгалтерии, если разделение итогов выключено, а текущие итоги не используются Возможна параллельная запись, если отличается счет или хотя бы одно измерение, уточнение про период см. нижеНабор записей регистра накопления (оборотов), если разделение итогов выключено Возможна параллельная запись, если отличается период (месяц) или хотя бы одно измерениеНабор записей регистра расчета без использования фактического периода действия Возможна параллельная запись наборов с разными регистраторамиНабор записей регистра сведений (подчиненный регистратору) Возможна параллельная запись наборов с разными регистраторамиЭлементы объектных типов: справочников, документов, планов видов характеристик, планов счетов (т. е. счета), планов видов расчета, бизнес-процессов, задач, планов обмена (т. е. узлы обмена) Возможна параллельная запись разных объектов, принадлежащих к одному типуНабор записей регистра накопления (остатков) при разрешенном и включенном режиме разделения итогов Возможна параллельная записьНабор записей регистра накопления (оборотов) при разрешенном и включенном режиме разделения итогов Возможна параллельная записьНабор записей регистра бухгалтерии при разрешенном и включенном режиме разделения итогов Возможна параллельная записьЭтим, однако, дело не вполне ограничивается. В автоматическом режиме управления блокировкой данных, когда используется уровень изоляции Serializable, сервером СУБД добавляется блокировка Key-range, которая защищает диапазон строк, считы- ваемый запросом, т. е. запрещает другим транзакциям вставлять в него строки, при этом также блокируются данные, соседние с диапазоном модифицируемых записей. В результате конфликтов на границах диапазонов реальная параллельность записи может быть ниже, чем указано в таблице, т. е., записи, которые теоретически должны бы записываться параллельно, могут не записаться.В управляемом режиме управления блокировкой данных такой проблемы нет.Но в управляемом режиме существует другая проблема. Сведения по параллель-ности, приведенные в таблице 3.11.1, изначально (начиная с книги «Професси-ональная разработка…») собирались по сведениям о параллельности для СУБД и не учитывали установки управляемых блокировок «1С» и принятия платформой решений о допустимости или недопустимости параллельной записи на их основе. Вопрос параллельности по периоду при включении и отключении текущих итогов в регистрах накопления (остатков) и регистрах бухгалтерии регулируется управляе-мыми блокировками «1С». Понятно, что установка управляемых блокировок парал-лельность улучшить не может, только снизить. Это и происходит с параллельностью по периоду в управляемом режиме, причем поведение системы в этом вопросе зависит от версии платформы и от установленного режима совместимости. В авто-матическом режиме возможна параллельная запись, если отличается период (месяц) при любом режиме текущих итогов.Проблема эскалации блокировок рассматривалась в разделе 3.10. Если происходит эскалация, то параллельная работа с такой таблицей становится невозможной.70 Настольная книга 1С:Эксперта по технологическим вопросамУзкие местаБолее подробно укажем узкие места и возможные решения проблем для самых тяжелых ситуаций.1. Константы. До версии 8.2.14 узким местом была таблица констант целиком. Все значения констант, определенных в конфигурации, хранились в одной таблице. Начиная с версии 8.2 .14 на каждую константу имеется собственная таблица, если не используется режим совместимости. Это позволяет записывать разные константы параллельно, но обычно проблема ошибочно написанного кода кроется как раз не в этом, а в том, что такой код пытается менять одну и ту же константу в разных сеансах, чего и новая структура делать тоже не позволяет. Назначение констант – хранить условно постоянные (очень редко изменяемые) данные, что следует из их названия. Общая рекомендация: не использовать константы для хранения данных, которые меняются чаще, чем раз в полгода, и никогда не использовать их для хранения быстро меняющихся данных (например, счетчиков). Причины ошибок блокировок, возникающих при неправильном использовании констант, диагно-стируются обычно очень просто: контекст кода, содержащий Константы.<имя>.Установить(…), будет виден в технологическом журнале, если настроить этот журнал, как указано в разделе 4.5.2. Граница регистрации последовательности. Данные каждой последовательности хранятся в двух таблицах: ■ таблица записей регистрации документов в последовательности, ■ таблица границ последовательности.Как происходит блокировка в этих таблицах при работе с последовательностями в клиент-серверном варианте работы, указано в таблице 3.11.2 . В файловом вари-анте при выполнении любого из перечисленных ниже действий таблицы блокиру-ются целиком.Таблица 3.11.2. Блокировка данных при работе с последовательностямиДействие Что блокируетсяТаблица записей регистрации документовв последовательности Таблица границ последовательностиРегистрация документа в по следовательности Диапазон записей, соответствующий одному регистратору (в автом. режиме управления блокировками – еще две «соседние») -Перемещение границы назад -По комбинации измерений после-довательности. Если измерений нет – таблица целикомПеремещение границы вперед Диапазон от границы последователь- ности по момент времени регистрации проводимого документа (с учетом измерений по следовательности) По комбинации измерений после-довательности. Если измерений нет – таблица целикомСудя по таблице, для последовательностей вроде бы существует возможность парал- лельного перемещения границы, которая достигается использованием измерений. Но в реальности сам смысл последовательностей очень часто либо не предполагает использования измерений вообще, либо предполагает использование единственного измерения «Организация», чего совершенно недостаточно для полноценной парал-лельной работы.71 ТеорияКак видно по таблице, регистрация документов в последовательности не несет вреда, а проблемной операцией является любое перемещение границы последо-вательности – как назад (узкое место – таблица границ последовательности), так и вперед (узким местом может быть любая из двух таблиц). Поэтому неправильно перемещать границу последовательности при проведении документов, перемещение должно происходить, например, регламентным заданием или служебной обработкой либо в нерабочее время, либо очень маленькими порциями, но очень часто, и, что важно, заниматься этим может одно рабочее место, никому не мешая. 23При этом не следует путать обработку по такому служебному перемещению границ с собственно восстановлением последовательности документов – это разные вещи29 .То, что ошибки блокировок возникают из-за автоматической регистрации документов в последовательностях, обычно сразу диагностируется по факту наличия таблиц с данными последовательностей в числе заблокированных.3. Выгрузка сообщений обмена.Если для объекта (речь об объекте метаданных, например, Справочник.Номенклатура (целиком!)) включена регистрация изменений для обмена, к нему добавляется еще одна таблица: таблица регистрации изменений. Эта таблица всегда одна на каждый прикладной объект, для которого возможна регистрация изменений, вне зависимости от количества планов обмена, а также от того факта, имеем мы дело с распреде-ленной базой или нет.Когда происходит выгрузка сообщений обмена, эта таблица блокируется для того, чтобы, пока данные выгружаются, никто не мог внести незарегистрированное изменение. То есть, пока мы выгружаем справочник Номенклатура, он целиком забло-кирован, и тот факт, что заблокирована не основная таблица, а служебная, дела не меняет. Понятно, что при таком поведении системы говорить о возможности парал-лельной работы при выгрузке практически не приходится.Поэтому выгрузку сообщений обмена рекомендуется проводить либо в нерабочее время, либо очень часто, так, чтобы за прошедшее с момента выгрузки время в системе не успевал накопиться объем измененных данных, выгрузка которого могла бы занимать сколь-нибудь существенное время.Что касается загрузки сообщений обмена, она, в отличие от выгрузки, по своему характеру не является настолько узким местом и по создаваемым проблемам сопо-ставима с групповой обработкой справочников и документов. 24В завершение еще один очень важный момент. И у загрузки, и у выгрузки обычно (в типовых решениях – обязательно) есть параметр «Количество элементов в транзакции». Если речь не идет о совсем простых случаях, не рекомендуется ставить значение этого параметра равным 0, то есть вся выгрузка, как и вся загрузка, совершенно точно не должна проходить в одной транзакции30. Значение этого 29 А также не следует путать автоматическое перемещение границы при проведении (регулируется в свойствах последовательностей) и автоматическую регистрацию документах в последовательности (регулируется в свойствах документов). Приносим извинения читателям за ошибку в первом издании. 30 Возможно, внешними по отношению к штатному транзакционному механизму средствами потребуется контролировать, что отработали все транзакции, и обеспечить целостность суммарных изменений, вносимых ими. Также иногда для обработок, состоящих из множества транзакций, есть смысл делать некоторую программную паузу между транзакциями. 72 Настольная книга 1С:Эксперта по технологическим вопросампараметра подбирается опытным путем, на практике нормально себя зарекомендо-вали значения от 1 до 100. 4. Набор записей регистра расчета с использованием фактического периодадействия.По данному вопросу приходилось слушать и читать полярные мнения: от того, что запись наборов записей регистра расчета с использованием фактического периода действия возможна только последовательно, до того, что запись этих наборов допу-скает параллельность по периоду и всем измерениям.Практический опыт показал, что существуют решения, допускающие параллельную запись, если отличается период действия (месяц, к которому он относится) или измерение, у которого стоит признак «базовое». Примером такого решения может служить конфигурация «Зарплата и кадры бюджетного учреждения», редакция 1.0 и решения на ее основе. И поскольку признак «базовое» стоит у измерения «Сотрудник», реальную параллельность записи в такой конфигурации можно оцени-вать как высокую.5. Набор записей регистра бухгалтерии.Если говорить только о записи в регистр бухгалтерии, следует отметить, что при прочих равных условиях скорость и параллельность записи в регистр бухгал-терии гораздо ниже, чем в регистры накопления. Например, при использовании бухгалтерского регистра работа по расчетам с покупателями возможна по одной организации только последовательная: есть всего два счета – 62.01 и 62.02, и вся запись идет в них.Если для регистра бухгалтерии разрешено и включено разделение итогов, то запись движений осуществляется с учетом сплиттера (разделителя итогов) и поэтому может производиться параллельно, даже при полностью совпадающих значениях периода, счета и измерений. 25Но параллельность увеличивается для записи, не для чтения31 . Что происходит, когда кроме записи есть чтение, уже описывалось выше, в разделе 3.9, в части, посвященной взаимоблокировкам. Если нужно осуществлять чтение, то разделитель итогов смысла не имеет, потому что читать надо все итоги по данным значениям периода, счета и измерений. Чтобы не получить взаимоблокировку, необходимо пользоваться свойством БлокироватьДляИзменения32 , которое есть у набора записей регистра бухгалтерии (подробнее описано в разделе 3.9). Таким образом, если идет чтение остатков, разделитель итогов параллельность не увеличивает. 26Кроме того, бухгалтерские документы, а именно они обычно являются источником записей в регистр бухгалтерии, могут в реальности перепроводиться пользова-телями в хаотичном порядке. Про эффект такого подхода см. ниже, в описании транзакций Запись + Запись.Про нюансы перепроведения документов, связанные с разделением итогов, см. в разделе 3.9. 31 Замечание про чтение справедливо, если не используется Read Committed Snapshot. 32 Необходимо помнить, что свойство БлокироватьДляИзменения реализовано с помощью установки управляемой блокировки в процессе записи набора, подробнее см. раздел 3.9. 73 Теория6. Набор записей регистра накопления.Когда разделение итогов выключено, при использовании регистра накопления есть гораздо больше возможностей организовать параллельную работу пользователей, чем при использовании регистра бухгалтерии – то, что было аналитическими разрезами (субконто), становится измерениями, и параллельная запись становится возможной там, где это было закрыто для регистра бухгалтерии. Нюансы работы, когда для регистра накопления разрешено и включено разделение итогов, полностью совпадают с аналогичными нюансами для регистра бухгалтерии, описанными выше, исключая наличие счета в регистрах накопления: разделитель перестанет увеличивать параллельность, если идет чтение остатков. Чтобы не полу- чить взаимоблокировку, необходимо пользоваться свойством БлокироватьДляИзме-нения.Перепроведение документов для регистров накопления вызывает те же трудности, что и для регистра бухгалтерии. Реальные транзакции Запись + ЗаписьКак правило, реальные транзакции содержат запросы на запись не только для одного объекта или только для одного набора записей, а для нескольких. И каждая новая блокировка уменьшает возможности по параллельной работе. Поэтому возможности параллельного выполнения транзакций определяются, во-первых, самой низкой возможностью из числа прикладных объектов конфигурации, запись которых в данной транзакции осуществляется, а во-вторых, конкретными (наихудшими) условиями записи конкретных объектов или наборов записей. Говоря проще, если в транзакции кроме прочего меняется значение константы или допускается эскалация блокировок на регистре бухгалтерии, этим сводятся на нет все возможности параллельной работы для прочих объектов метаданных, записываемых в той же транзакции.Существует хорошая рекомендация осуществлять запись движений и контроль остатков как можно ближе к концу транзакции. Она, однако, теряет смысл, когда документы разрешается перепроводить, но при этом никогда не выполняется анализ, надо ли очищать движения и записывать новые. В такой ситуации всегда имеет место установка исключительной блокировки на ресурсы практически в самом начале транзакции.Реальные транзакции Чтение + Запись3327Про нюансы работы режима, когда в регистре бухгалтерии или в регистре нако-пления разрешено и включено разделение итогов, говорилось выше. Но этот механизм работает так, как было описано, даже когда речь идет не об избыточных блокировках, а о необходимых.Далее же речь пойдет именно об избыточных блокировках. Потому что, в отличие от запросов на запись, при написании запросов на чтение у разработчика прикладного решения (конфигурации) есть много возможностей поставить избы-точные блокировки. Как говорилось ранее в разделе 3.9, посвященном ошибкам 33 Если вы используете уровень изоляции Read Committed Snapshot (8.3 без режима совместимости + MS SQL Server 2005 и старше), вы можете забыть про сложности с разделяемыми блокировками СУБД, они не устанавливаются.74 Настольная книга 1С:Эксперта по технологическим вопросамблокировок, это приводит к таким ошибкам даже тогда, когда запись может осущест- вляться и осуществляется параллельно.Далее, как отмечалось там же, работа некоторых механизмов «1С» приводит к избы-точным блокировкам именно, точнее чаще, при чтении.1. Разделение доступа к данным на уровне записей. RLS –Record Level Security. При этом каждая новая роль, содержащая ограничение, добавляет к каждому запросу к базе, содержащему реквизит, по которому идет разделение, свое соеди-нение в соответствии с дополнительным запросом, написанным в конфигураторе (в типовых конфигураций их обычно размещают в шаблонах ролей). Пример такого запроса приведен на рис. 3.11 .1. В итоге каждый запрос отличается от «чистого» запроса тех же данных. Поскольку ограничение чаще устанавливается на чтение, а на запись реже (но тоже иногда встречается), то частая ситуация – запрос на чтение отличается от «чистого» запроса, а запрос на запись соответствует «чистому»34 . 28Если &ИспользоватьОграничениеПоОрганизации #ТогдаТекущаяТаблица ИЗ#ТекущаяТаблица КАК ТекущаяТаблица ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕСоставГруппы.Ссылка КАК ГруппаПользователей ИЗСправочник.ГруппыПользователей.ПользователиГруппы КАК СоставГруппыГДЕСоставГруппы.Пользователь =&ТекущийПользователь) КАК ГруппыПользователей ПО (ИСТИНА)ГДЕНЕ ГруппыПользователей.ГруппаПользователей ЕСТЬ NULLИ(НЕ1В(ВЫБРАТЬ ПЕРВЫЕ 11ИЗРегистрСведений.НазначениеВидовОбъектовДоступа КАК НазначениеВидовОбъектовДоступаЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАКНастройкиПравДоступаПользователей ПОНастройкиПравДоступаПользователей.ОбъектДоступа =ТекущаяТаблица.#Параметр(1)И НастройкиПравДоступаПользователей.ВидОбъектаДоступа =НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа И НастройкиПравДоступаПользователей.ОбластьДанных =ЗНАЧЕНИЕ(Перечисление.ОбластиДанныхОбъектовДоступа.ПустаяСсылка) И НастройкиПравДоступаПользователей.Пользователь =ГруппыПользователей.ГруппаПользователейГДЕНазначениеВидовОбъектовДоступа.ГруппаПользователей =ГруппыПользователей.ГруппаПользователей И НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа В (ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Организации))И НастройкиПравДоступаПользователей.ОбъектДоступа ЕСТЬ NULL))#КонецЕслиРис. 3.11.1. Пример запроса, дописываемого к основному подсистемой RLS. 1С:УПП 1.3.39.1,роль «Бухгалтер МСФО», ограничение чтения по организации (для указанной роли,в частности, используется на регистр бухгалтерии «Хозрасчетный»)34 Примечание ко второму изданию: на текущий момент работу механизма RLS можно отследить в профайлере по наличию характерных конструкций в тексте запроса, в частности, по наличию «SDBL_DUMMY». Мы, разумеется, не готовы утверждать, что так было всегда и что это будет продолжаться и дальше, но сейчас это так.75 ТеорияТакие дописываемые запросы осложняют жизнь не только тем, что приходится полу- чать дополнительные данные, и даже, можно сказать, что совсем не тем. Основная проблема, которую они создают, состоит в том, что наличие подобных соединений очень сильно мешает использовать поиск по индексу и очень часто приводит к сканированию индекса или таблицы, то есть и к избыточным блокировкам, и к увеличению длительности выполнения запросов.Вспомним Светочку с Леночкой из раздела 3.9 .Для борьбы за повышение производительности труда бумажные документы, с кото-рыми работали Светочка и Леночка, «проиндексировали». Для этого, во-первых, документы стали класть в пластиковые файлы отдельного цвета, в зависимости от того, за какой месяц документ; во-вторых, цветной скрепкой стали обозначать, к какой организации документ относится (периодический регистр сведений с однимизмерением или регистр накопления с одним измерением).После этого стало достаточно давать каждой из девушек задания по работе со своими отдельными организациями, и работа наладилась (возможность параллельнойработы).Однако систему решили улучшить: работу с документами решили не только регули-ровать заданием, но и ограничением доступа.В один прекрасный день Светочка получила следующее задание: «обработать доку-менты за сентябрь (пластиковые файлы красного цвета) по организации «А-один» (синяя скрепка), учтя при этом, что она может работать только с документами организаций «А-один» и «Б-два» (красная скрепка)». Леночка получила задание: «обработать документы за сентябрь (пластиковые файлы красного цвета) по орга-низации «В-три» (зеленая скрепка), учтя при этом, что она может работать только с документами организаций «В-три» и «Г-четыре» (желтая скрепка)».Девушки напряглись. Светочка смогла сопоставить второе условие с третьим и сразу взяла только красные файлы с синей скрепкой. Леночка не смогла. Она сначала взяла красные файлы с зелеными и желтыми скрепками, но почти сразу файлы с желтыми скрепками вернула на место (избыточная блокировка на чтение,не приведшая к конфликту). Поскольку обе девушки выполнили работу, эксперимент был признан удачным, и вскоре его распространили на всю фирму. Придя на работу, Светочка получила следующее задание: «обработать документы за сентябрь (пластиковые файлы крас-ного цвета) по организации «А-один» (синяя скрепка), учтя при этом, что список ограничений (организаций, контрагентов, видов документов и др.), с которыми она может работать, висит на стенде в административном здании».Периодов (месяцев) в качестве ограничений указано не было. Кроме того, все файлы были отсортированы по цветам, и пластиковые файлы красного цвета лежали рядом (кластерный индекс). Что это за условия, Светочка не знала, и сможет ли она их запомнить, сомневалась. Поэтому она, не задумываясь, взяла все красные файлы, пошла с ними в административный корпус, там прочитала условие и, постоянно с ним сверяясь, выбрала по нему те документы, с которыми ей можно работать, из них выбрала файлы с синей скрепкой, остальные вернула на место.76 Настольная книга 1С:Эксперта по технологическим вопросамЛеночка это видела. Она заметила, что вся эта операция не заняла особенно много времени и что ходить в административный корпус Светочке пришлось только один раз. Поэтому она решила применить ту же самую тактику. Одна незадача: ее тоже попросили обработать документы за сентябрь (пластиковые файлы красного цвета), хотя и по другой организации. Но поскольку Леночке согласно ее тактике для проверки условий требовались все документы из красных файлов (попытка устано-вить избыточную блокировку на чтение), она их снова так и не дождалась и ушла в шесть вечера домой, так и не начав работать (таймаут).Данный пример, кроме иллюстрации возникновения избыточной блокировки при чтении, использующем ограничения на уровне записей, демонстрирует еще одну закономерность. Чем более сложные и универсальные механизмы ограничения доступа строятся, тем менее следует надеяться, что оптимизатор СУБД распознает эти ограничения как имеющиеся у таблиц индексированные поля, хотя бы они и были таковыми, и тем выше вероятность, что будет иметь место сканирование индекса или таблицы.Одним из вариантов решения проблем, когда видно, что избыточные блокировки возникают именно при чтении и именно при работе RLS, может быть отключение RLS, притом только на время транзакции, с отработкой исключительной ситуации, например, следующим кодом35:29ТекущееЗначениеПараметра =ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей;ПопыткаПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей =Ложь;Запрос.Выполнить();ПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей =ТекущееЗначениеПараметра;ИсключениеПараметрыСеанса.ИспользоватьОграниченияПравДоступаНаУровнеЗаписей =ТекущееЗначениеПараметра;ВызватьИсключение;КонецПопытки;2. Использование разделения данных.Сразу надо предупредить, что использование разделения данных для целей, приве-денных ниже, нигде не рекомендовано. Напротив, пример приведен специально для предупреждения о возможных последствиях такого подхода.Рассмотрим частный и, повторим, заведомо ошибочный случай, когда разделение данных используется как разграничитель доступа по организациям.Ситуация поворачивается наоборот: теперь пользователь с максимальными полно-мочиями оказывается в проигрыше.35 Пример взят из практики, в нем нормально отрабатываются случаи с ошибкой и разрывом соединения, потому что RLS отключается только на время одного запроса на чтение. Пример, однако, не идеален, он не будет корректно работать, в частности, в ситуации, когда в транзакции ранее уже была ошибка, заключенная в скобки «Попытка – Исключение», а Запрос.Выполнить() – первое чтение после этой ошибки, которое вернет сообщение «в данной транзакции уже происходили ошибки!». Лучше, хотя и не всегда проще, использовать привилегированный режим. Этот режим как раз существует для таких случаев, но в клиент-серверном варианте при выполнении на клиенте данный метод не выполняет никаких действий, и при работе с обычным приложением потребуются дополнительные усилия по переносу кода в серверные общие модули.77 ТеорияСветочке и Леночке выделили по шкафу. Их документы теперь кладут только в эти шкафы. Девушкам не приходится ждать друг друга, они могут нормально работать. Но теперь проблемы начались у их начальника. Чтобы работать с документами, ему надо открыть и держать открытыми оба шкафа, он не может эффективно использо-вать поиск и брать стопку документов одним движением. Если использовать независимый разделитель, то ни у одного пользователя физи-чески не будет доступа ко всем данным. Например, Светочка будет иметь доступ к документам организации «А-один», Леночка к документам организации «В-три», но невозможно будет создать роль, которая имела бы доступ ко всем документам. Если использовать независимый и совместный разделитель, то такая роль будет возможна. Появится возможность разрешить некоторым пользователям заходить в базу без указания значения разделителя, и эти пользователи будут видеть все данные. Но эффективной работы с этими данными не получится. Поскольку во всех индексах первым полем будет идти разделитель (точнее хеш-функция разделителей, см. раздел 3.13 «Сведения об индексах базы»), а пользователь с максимальными полномочиями будет работать без указания разделителя, то все запросы будут выпол- няться со сканированием: медленно и с избыточными блокировками. Это будет очень печально, потому что максимальные полномочия обычно предоставляют не рядовым пользователям, а наиболее толковым из них, а также начальству. И выйдет так, что именно у наиболее грамотных пользователей и у начальства запросы будут работать хуже. Как описывалось раньше, избыточные блокировки приведут к тому, что возможности параллельной работы транзакций серьезно уменьшатся36 . 303.12. Сведения о размещении данных. Способполучения этих сведенийС самого начала этого раздела скажем, что сведения, приведенные в нем, совершенно не обязательно учить наизусть или носить с собой в виде шпаргалки. Чтобы не зави- сеть от особенностей базы, связанных с версией релиза, режимом совместимости и др., нужно просто помнить, что их всегда можно вызвать из вашей базы кодом:ТаблицаСоСтруктурой =ПолучитьСтруктуруХраненияБазыДанных();ТаблицаСоСтруктурой.Сортировать(“Метаданные, ИмяТаблицыХранения”);Функция глобального контекста ПолучитьСтруктуруХраненияБазыДанных() возвра-щает таблицу значений, доступна на сервере, в толстом клиенте и внешнем соединении. Полученную таблицу значений сразу есть смысл отсортировать и затем любым известным способом вывести на форму. Также можно просто посмотреть ее на останове в отладчике и сразу там же вывести в табличный документ, чтобы иметь все возможности и удобства по работе с полученным списком: поиск, сохра- нение и др. 36 Теоретически эта проблема может быть решена путем добавления индексов, таких же по составу, но без разделителя, если используется независимый и совместный разделитель. До реализации дело пока не дошло.78 Настольная книга 1С:Эксперта по технологическим вопросамСоздадим пустую базу37 . В ней создадим три прикладных объекта: Константа1, Константа2 и Справочник1. Сохраним изменения в базе и посмотрим на ее струк-туру описанным выше способом (в таблице 3.12 .1 приведены только интересующие нас столбцы). 31Таблица 3.12 .1. Имена таблиц, изначально созданныхпри организации с нуля базы с двумя константами и справочникомИмя таблицыхранения Имя таблицы Метаданные Назначение”SystemSettings” “” “””ХранилищеСистемныхНастроек””CommonSettings” “” “””ХранилищеОбщихНастроек””RepSettings” “” “””ХранилищеПользовательскихНа-строекОтчетов””RepVarSettings” “” “””ХранилищеВариантовОтчетов””FrmDtSettings” “” “””ХранилищеНастроекДанныхФорм””UsersWorkHistory” “” “””ИсторияРаботыПользователей””Const8” “””Константа.Константа1” “Константа””Const10” “””Константа.Константа2” “Константа””Reference7” “Справочник.Справочник1” “Справочник.Спра-вочник1” “Основная”Мы работаем с релизом 8.2 .18, без использования режима совместимости, поэтому каждая константа хранится в своей таблице. Если переключить режим совмести-мости, останется одна таблица, отвечающая за все константы38 . 32Как будут выглядеть эти таблицы, если на эту же базу в клиент-серверной версии «1С» посмотреть средствами SQL, показано на рис. 3.12 .1. Рис. 3.12.1. Имена таблиц, изначально созданных файловой версией при созданиис нуля базы с двумя константами и справочником после загрузкив клиент-серверную версию и просмотре через SQL Server Management Studio37 Поведение в файловой и клиент-серверной версии должно быть одинаковым. 38 При другом составе метаданных будут и другие изменения состава таблиц, возникшие вследствие изменения режима совместимости. 79 ТеорияИз приведенных выше таблицы 3.12 .1 и рисунка 3.12 .1 делаем выводы:1. Функция глобального контекста ПолучитьСтруктуруХраненияБазыДанных() пока- зывает не все таблицы (не показаны обязательные39 таблицы: Config, ConfigSafe и т. д.) . 332. Нам для решения практических задач по нашей теме и понимания структуры хранения данных вполне достаточно и того, что она показывает.3. Названия таблиц в колонке ИмяТаблицыХранения и имена таблиц в СУБД сопо-ставимы.4. Имя таблицы состоит из префикса и номера. По префиксу можно понять, что это за таблица (или посмотреть колонку Метаданные). Номер присваивается системой в сквозном порядке, но с пропусками.В предыдущей главе обсуждалась выгрузка сообщений обмена как узкое место при параллельной работе. Создадим план обмена и включим в него Константу2 и Спра-вочник1, а Константу1 включать не будем. В таблице 3.12.2 видно, какие таблицы для каких объектов метаданных добавились. При добавлении еще одного плана обмена и включении регистрации в нем Константы2 и Справочника1 новые таблицы для них не появятся. В дальнейшем новые объекты включать в план обмена не будем, чтобы не загромождать материал. Скажем только, что ровно по одной таблице с назначе-нием «РегистрацияИзменений» и подстрокой «ChngR» в имени будет создано для каждого из объектов метаданных, зарегистрированных хотя бы в одном плане обмена.Таблица 3.12 .2. Имена таблиц, добавленных к таблицам объектом метаданныхпосле включения их в план обменаИмя таблицыхранения Имя таблицы Метаданные Назначение”SystemSettings” “” “””ХранилищеСистемныхНа-строек””CommonSettings” “” “””ХранилищеОбщихНастроек””RepSettings” “” “””ХранилищеПользователь-скихНастроекОтчетов””RepVarSettings” “” “””ХранилищеВариантовОт-четов””FrmDtSettings” “” “””ХранилищеНастроекДанных-Форм””UsersWorkHistory” “” “””ИсторияРаботыПользова-телей””Const8” “””Константа.Константа1” “Константа””Const10” “””Константа.Константа2” “Константа””ConstChngR15” “””Константа.Константа2” “РегистрацияИзмененийКон-станты””Node13” “ПланОбмена.ПланОбмена1” “ПланОбмена.ПланОбмена1” “Основная””Reference7” “Справочник.Справочник1” “Справочник.Справочник1” “Основная””ReferenceChngR14” “””Справочник.Справочник1” “РегистрацияИзменений”39 Обязательными они называется потому, что при их отсутствии система не считает имеющуюся базу базой «1С:Предприятия».80 Настольная книга 1С:Эксперта по технологическим вопросамСоздадим по одному объекту каждого вида.Объектам, которые могут иметь табличные части, добавим их (одному из доку-ментов – две). Обратим внимание на то, что, когда мы получаем информацию о структуре через останов на отладчике (см. рис. 3.12 .2), элементами строки, отвечающей за таблицу, являются также вложенные таблицы значений: «Индексы» и «Поля». Через них можно получить сведения о структуре индексов и структуре полей, и в двух следу-ющих главах мы эти средством воспользуемся.Рис. 3.12.2. Просмотр структуры базы через останов на отладчике. Видны вложенныетаблицы «Индексы» и «Поля»В таблице 3.12 .3 представлены созданные таблицы базы. В столбце «Назначение» для некоторых таблиц курсивом добавлено условие, при котором эта таблица добав-ляется, если такое условие требует пояснения.Таблица 3.12 .3. Пример имен таблиц, созданных в базе. В базу добавлены все возможные объектыИмя таблицыхранения Имя таблицы Метаданные НазначениеСлужебные”CommonSettings” “” “””ХранилищеОбщихНастроек””ExtDataSrcPrms” “” “””Основная””FrmDtSettings” “” “””ХранилищеНастроекДанныхФорм””RepSettings” “” “””ХранилищеПользовательскихНа-строекОтчетов””RepVarSettings” “” “””ХранилищеВариантовОтчетов””SystemSettings” “” “””ХранилищеСистемныхНастроек””UsersWorkHistory” “” “””ИсторияРаботыПользователей”Бизнес-процессы”BPr23” “БизнесПроцесс.БизнесПроцесс1” “БизнесПроцесс.БизнесПроцесс1” “Основная””BPrPoints24” “””БизнесПроцесс.БизнесПроцесс1” “ТочкиМаршрута””BPr23.VT60” “БизнесПроцесс.БизнесПроцесс1.ТабличнаяЧасть1” “БизнесПроцесс.БизнесПроцесс1.ТабличнаяЧасть.ТабличнаяЧасть1” “ТабличнаяЧасть”Документы”Document16” “Документ.Документ1” “Документ.Документ1” “Основная””Document16.VT47” “Документ.Документ1.ТабличнаяЧасть1” “Документ.Документ1.ТабличнаяЧасть.ТабличнаяЧасть1” “ТабличнаяЧасть””Document16.VT49” “Документ.Документ1.ТабличнаяЧасть2” “Документ.Документ1.ТабличнаяЧасть.ТабличнаяЧасть2” “ТабличнаяЧасть”Журналы документов”DocumentJournal37” “ЖурналДокументов.ЖурналДокументов1” “ЖурналДокументов.ЖурналДокументов1” “Основная”81 ТеорияИмя таблицыхранения Имя таблицы Метаданные НазначениеЗадачи”Task25” “Задача.Задача1” “Задача.Задача1” “Основная””Task25.VT62” “Задача.Задача1.ТабличнаяЧасть1” “Задача.Задача1.ТабличнаяЧасть.ТабличнаяЧасть1” “ТабличнаяЧасть”Константы”Const8” “””Константа.Константа1” “Константа””Const10” “””Константа.Константа2” “Константа””ConstChngR15” “””Константа.Константа2” “РегистрацияИзмененийКонстанты”Перечисления”Enum26” “Перечисление.Перечисление1” “Перечисление.Перечисление1” “Основная”Планы видов расчета”CKinds21” “ПланВидовРасчета.ПланВидовРас-чета1” “ПланВидовРасчета.ПланВидовРас-чета1” “Основная””CKindsDN86” “””ПланВидовРасчета.ПланВидовРас-чета1” “ПорядокВытеснения” (создается,если у плана видов расчета уста-новлен флажок ИспользуетПе-риодДействия)”CKinds21.BaseCK” “ПланВидовРасчета.ПланВидовРасче-та1.БазовыеВидыРасчета” “ПланВидовРасчета.ПланВидовРас-чета1.ТабличнаяЧасть.БазовыеВи-дыРасчета” “БазовыеВидыРасчета” (создается,если у плана видов расчета свой-ство “Зависимость от базы” не “Независит”)”CKinds21.LeadingCK” “ПланВидовРасчета.ПланВидовРасче-та1.ВедущиеВидыРасчета” “ПланВидовРасчета.ПланВидовРас-чета1.ТабличнаяЧасть.ВедущиеВи-дыРасчета” “ВедущиеВидыРасчета””CKinds21.DisplacedCK” “ПланВидовРасчета.ПланВидовРасче-та1.ВытесняющиеВидыРасчета” “ПланВидовРасчета.ПланВидовРас-чета1.ТабличнаяЧасть.Вытесняю-щиеВидыРасчета” “ВытесняющиеВидыРасчета”(создается, если у плана видов рас-чета установлен флажок Использу-етПериодДействия)”CKinds21.VT58” “ПланВидовРасчета.ПланВидовРасче-та1.ТабличнаяЧасть1” “ПланВидовРасчета.ПланВидовРас-чета1.ТабличнаяЧасть.Таблична-яЧасть1” “ТабличнаяЧасть”Планы видов характеристик”Chrc27” “ПланВидовХарактеристик.ПланВи-довХарактеристик1” “ПланВидовХарактеристик.ПланВи-довХарактеристик1” “Основная””Chrc27.VT51” “ПланВидовХарактеристик.ПланВи-довХарактеристик1.ТабличнаяЧасть1” “ПланВидовХарактеристик.План-ВидовХарактеристик1.Табличная-Часть.ТабличнаяЧасть1” “ТабличнаяЧасть”Планы обмена”Node13” “ПланОбмена.ПланОбмена1” “ПланОбмена.ПланОбмена1” “Основная””Node13.VT56” “ПланОбмена.ПланОбмена1.Таблич-наяЧасть1” “ПланОбмена.ПланОбмена1.Та-бличнаяЧасть.ТабличнаяЧасть1” “ТабличнаяЧасть”Планы счетов”Acc22” “ПланСчетов.ПланСчетов1” “ПланСчетов.ПланСчетов1” “Основная””Acc22.ExtDim72” “ПланСчетов.ПланСчетов1.ВидыСуб-конто”(создается, если максимальноеколичество субконто больше 0) “ПланСчетов.ПланСчетов1.Таблич-наяЧасть.ВидыСубконто” “ВидыСубконто””Acc22.VT53” “ПланСчетов.ПланСчетов1.Таблич-наяЧасть1” “ПланСчетов.ПланСчетов1.Таблич-наяЧасть.ТабличнаяЧасть1” “ТабличнаяЧасть”Последовательности”Seq41” “Последовательность.Последователь-ность1” “Последовательность.Последова-тельность1” “Основная””SeqB42” “””Последовательность.Последова-тельность1” “ГраницыПоследовательности”Регистры бухгалтерии”AccRg28” “РегистрБухгалтерии.РегистрБухгал-терии1” “РегистрБухгалтерии.РегистрБух-галтерии1” “Основная”82 Настольная книга 1С:Эксперта по технологическим вопросамИмя таблицыхранения Имя таблицы Метаданные Назначение”AccRgAT030” “””РегистрБухгалтерии.РегистрБух-галтерии1” “ИтогиПоСчетам””AccRgAT174” “””РегистрБухгалтерии.РегистрБух-галтерии1” “ИтогиПоСчетамССубконто1″(создается, если максимальноеколичество субконто у плана счетовбольше 0)”AccRgAT275” “””РегистрБухгалтерии.РегистрБух-галтерии1” “ИтогиПоСчетамССубконто2″(создается, если максимальноеколичество субконто у плана счетовбольше 1)”AccRgCT65” “””РегистрБухгалтерии.РегистрБух-галтерии1” “ИтогиМеждуСчетами” “(создается, если регистр поддержи-вает корреспонденцию)”AccRgED77” “”””РегистрБухгалтерии.РегистрБух-галтерии1” “ЗначенияСубконто”(создается, если максимальноеколичество субконто у плана счетовбольше 0)”AccRgOpt34” “””РегистрБухгалтерии.РегистрБух-галтерии1” “НастройкиХраненияИтоговРеги-страБухгалтерии”Регистры накопления типа «Остатки»”AccumRg17” “РегистрНакопления.РегистрНако-пления1” “РегистрНакопления.РегистрНако-пления1” “Основная””AccumRgAggGrid92” “””РегистрНакопления.РегистрНако-пления1” “СписокАгрегатовРегистровНако-пления”(создалась после создания агрега-тов для Регистра накопления2)”AccumRgAggOpt94” “””РегистрНакопления.РегистрНако-пления1” “НастройкиРежимаАгрегатовРеги-стровНакопления” “(создалась после создания агрега-тов для Регистра накопления2)”AccumRgOpt20” “””РегистрНакопления.РегистрНако-пления1” “НастройкиХраненияИтоговРеги-страНакопления””AccumRgT19” “””РегистрНакопления.РегистрНако-пления1” “Итоги”Регистры накопления типа «Обороты»”AccumRg78” “РегистрНакопления.РегистрНако-пления2” “РегистрНакопления.РегистрНако-пления2” “Основная””AccumRgAgg31h97” “””РегистрНакопления.РегистрНако-пления2” “АгрегатРегистраНакопления” (соз-далась после создания агрегатов)”AccumRgAggGrid93″ “””РегистрНакопления.РегистрНако-пления2” “СписокАгрегатовРегистровНако-пления”(создалась после создания агре-гатов)”AccumRgAggOpt95” “””РегистрНакопления.РегистрНако-пления2” “НастройкиРежимаАгрегатовРеги-стровНакопления”(создалась после создания агре-гатов)”AccumRgBf99” “””РегистрНакопления.РегистрНако-пления2” “БуферОборотов”(создалась после создания агре-гатов)”AccumRgDl98” “””РегистрНакопления.РегистрНако-пления2” “НовыеОбороты”(создалась после создания агре-гатов)83 ТеорияИмя таблицыхранения Имя таблицы Метаданные Назначение”AccumRgOpt79” “””РегистрНакопления.РегистрНако-пления2” “НастройкиХраненияИтоговРеги-страНакопления””AccumRgSt100” “””РегистрНакопления.РегистрНако-пления2” “СтатистикаЗапросов”(создалась после создания агре-гатов)”AccumRgTn85” “””РегистрНакопления.РегистрНако-пления2” “Обороты”(создается, если есть хоть одноизмерение)Регистры расчета”CRg36” “РегистрРасчета.РегистрРасчета1” “РегистрРасчета.РегистрРасчета1” “Основная””CRgActP88” “””РегистрРасчета.РегистрРасчета1” “ПериодыДействия” (создается,если установлено свойство “Периоддействия” )”CRgRecalc87″ “РегистрРасчета.РегистрРасчета1.Перерасчет.Перерасчет1” “РегистрРасчета.РегистрРасчета1.Перерасчет.Перерасчет1” “Основная” (создается, если добав-лен перерасчет )Регистры сведений”InfoRg38″ “РегистрСведений.РегистрСведений1” “РегистрСведений.РегистрСве-дений1” “Основная”Справочники”Reference7” “Справочник.Справочник1” “Справочник.Справочник1” “Основная””ReferenceChngR14” “””Справочник.Справочник1” “РегистрацияИзменений””Reference7.VT45” “Справочник.Справочник1.Таблична-яЧасть1” “Справочник.Справочник1.Таблич-наяЧасть.ТабличнаяЧасть1” “ТабличнаяЧасть”Несколько комментариев к таблице:1. Табличная часть объекта в первой части префикса содержит префикс объекта, см., напр., «Document16» и «Document16.VT47».2. К таблице точек маршрута бизнес-процесса и к некоторым другим таблицам это не относится.3. Понятно, что в условиях другой конкретной базы нумерация таблиц и их коли-чество будут другими. После изменения релиза могут измениться и их имена, хотя бы и незначительно. Могут появляться новые виды таблиц, как появились отдельные таблицы под каждую константу и таблицы, связанные с агрега-тами. Главное – понимать, как и откуда вы эти данные можете получить и как полученные из вашей базы особенности размещения данных влияют на парал-лельность работы.84 Настольная книга 1С:Эксперта по технологическим вопросам3.13. Сведения об индексах базы.Способ получения этих сведений.Кластерный и некластерные индексыПодход к получению сведений об индексах может быть таким же, как тот, что мы использовали в предыдущей главе: не имея справочников, с помощью кода получить в отладчике структуру хранения данных:ТаблицаСоСтруктурой =ПолучитьСтруктуруХраненияБазыДанных();ТаблицаСоСтруктурой.Сортировать(“Метаданные, ИмяТаблицыХранения”);Далее, спускаясь по структуре (расшифровываемые поля на рис. 3.13.1 подсвечены), узнать, какие есть индексы:85 ТеорияРис. 3.13.1. Получение сведений об индексе непосредственно из базыВ примере на рисунках выше выяснено, что у таблицы документов один из индексов идет по номеру и ссылке.Также из рисунков этого примера видно, как вообще добраться до информации об индексах. Нужно из первоначальной таблицы значений, в которую была получена структура базы, пройти по вложенной в нее таблице «Индексы», а из «Индексов» – пройти по таблице значений «Поля». Написание обработки, проходящей два уровня вложенных таблиц, затруднений вызвать не должно. Запустив ее, получим реально существующий состав индексов для нашей базы (в таблице 3.13.1 приведен его фрагмент). В колонке «Имя поля» курсивом дописаны описания на русском языке, не формирующиеся автоматически.Таблица 3.13.1. Индексы, созданные в базе (фрагмент)Имя таблицыхранения Метаданные + назначение Имяиндекса Имя поля хранения Имя поля”Const8″ “Константа.Константа1Константа””” “””ByKey” “RecordKey” “””Const10” “Константа.Константа2Константа””” “””ByKey” “RecordKey” “””ConstChngR15” “Константа.Константа2РегистрацияИзмененийКонстанты””” “””ByNodeMsg” “Node, MessageNo, ConstID” “, , “(Узел + Номерсообщения + Ключданных) “” “””ByDataKey” “ConstID, Node” “,”(Ключ данных + Узел)”Document16” “Документ.Документ1Основная””” “””ByDocNum” “Number, ID” “Номер, Ссылка””” “””ByDocDate” “Date_Time, ID” “Дата, Ссылка””DocumentJournal37” “ЖурналДокументов.ЖурналДокументов1Основная””” “””ByDocDate” “Date_Time, Document” “Дата, Ссылка””” “””ByDoc” “Document” “Ссылка””Enum26” “Перечисление.Перечисление1Основная””” “””ByOrder” “EnumOrder, ID” “Порядок, Ссылка””Seq41” “Последовательность.Последовательность1Основная””” “””ByRecorder” “Recorder” “Регистратор””” “””ByDims” “Period, Recorder” “Период, Регистратор””AccumRg17” “РегистрНакопления.РегистрНакопления1Основная””” “””ByPeriod” “Period, Recorder, LineNo” “Период, Регистратор,НомерСтроки”86 Настольная книга 1С:Эксперта по технологическим вопросамИмя таблицыхранения Метаданные + назначение Имяиндекса Имя поля хранения Имя поля”” “””ByRecorder” “Recorder, LineNo” “Регистратор,НомерСтроки””AccumRgAggGrid92” “РегистрНакопления.РегистрНакопления1СписокАгрегатовРегистровНакопления””” “””ByID” “RegID, DefaultPeriodic,ID, Updated” “,,,””AccumRgAggOpt94” “РегистрНакопления.РегистрНакопления1НастройкиРежимаАгрегатовРегистровНакопления””” “””ByID” “RegID” “””AccumRgOpt20” “РегистрНакопления.РегистрНакопления1НастройкиХраненияИтоговРегистраНакопления””” “””ByRegID” “RegID” “””AccumRgT19” “РегистрНакопления.РегистрНакопления1Итоги””” “””ByDims” “Period, Fld96, Splitter” “, Измерение1, “”InfoRg38” “РегистрСведений.РегистрСведений1Основная””” “””ByDims” “Fld39” “Измерение1″”Reference7” “Справочник.Справочник1Основная””” “””Code” “Code, ID” “Код, Ссылка””” “””Descr” “Description, ID” “Наименование, Ссылка””ReferenceChngR14” “Справочник.Справочник1РегистрацияИзменений””” “””ByNodeMsg” “Node, MessageNo, ID” “,,”(Узел + Номер сооб-щения + Ключ данных) “” “””ByDataKey” “ID, Node” “,”(Ключ данных + Узел)Описанный способ получения существующих индексов не выводит, однако, есть нескольких важных вещей:1. Для всех объектных типов данных (справочники, документы и т. д.) в базе авто-матически определяется кластерный индекс по полю Ссылка. И вот его в этой таблице вы не увидите, но про него надо просто помнить.2. При использовании общего реквизита к большинству индексов первым столбцом ключа индекса добавляется DataSeparationHash. Этого факта, к сожа-лению, через ПолучитьСтруктуруХраненияБазыДанных() вы тоже не увидите, и про него тоже надо помнить40 . 343. Также в этой таблице вы не увидите индекса simplekey для регистра сведений, но он для наших целей важности не имеет.Кластерным называется индекс, по значению которого отсортирована таблица в базе. Остальные индексы называются некластерными. Таблица может иметь только один кластерный индекс или не иметь ни одного. Некластерных индексов может быть несколько, или может не быть совсем.Кластерный индекс для необъектных типов данных, в отличие от объектных, в таблицу, получаемую через ПолучитьСтруктуруХраненияБазыДанных(), попадает. В таблице выше кластерные индексы выделены жирным шрифтом.Данные по тому, какие индексы являются кластерными, получены как из литера-туры, так и через просмотр свойств базы средствами SQL Server Management Studio. Этот альтернативный предложенному ранее способ получения информации о струк-40 Также см. сноску в конце раздела 3.11.87 Теориятуре базы более точен (видны все таблицы, все индексы, все реквизиты, по которым индекс строится), но значительно менее удобен в том, что нет привязки к именам таблиц в терминах метаданных, а также в том, что годится только для SQL Server. К слову, создание индексов не через конфигуратор, а средствами сервера СУБД строго не рекомендуется и, кроме прочего, нарушает лицензионное соглашение.Далее, хотя мы описали методику получения фактического состава индексов в базе, нелишним будет привести сведения по текущим правилам построения индексов хотя бы для справочников, документов, регистров сведений, накопления и бухгалтерии41 , т. е. для того, с чем чаще всего приходится иметь дело. Использованы фрагменты статьи http://its.1c.ru/db/metod8dev#content:1590:hdoc с сайта ИТС, статья находится в открытом доступе. 35<…> Индексы таблиц создаются неявным образом при создании объектов конфи-гурации, а также при тех или иных настройках объектов конфигурации. Для тех случаев, когда создание индексов зависит от настроек объектов конфигурации, приведены условия создания индексов. В приведенных ниже таблицах имена индексных полей приведены так, как они описаны в разделе документации «Таблицы запросов».Для измерений, реквизитов и т. д. применяются условные имена Измерение1, Реквизит1 и т. д.Для общих реквизитов, являющихся разделителями в режиме «независимо», будем использовать имена ОРНР (ОРНР1, ОРНР2, и т. д.) .Для общих реквизитов, являющихся разделителями в режиме «независимо и совместно», будем использовать имена ОРСР.Если режим разделения не имеет значения, то для общих реквизитов, являющихся разделителями, будем использовать имена ОРР.Если в конфигурации определены разделители, то в индексы может входить поле, которое содержит значение хеш-функции набора значений разделителей. Такое поле будем обозначать именем ОРРХ.Те индексные поля, которые не являются обязательными, приведены в квадратных скобках, а если в индексе присутствует набор однотипных полей, это описывается многоточием, например: Реквизит + Измерение1 + [Измерение2 +…] .Данным материалом следует руководствоваться при написании текстов запросов с целью оптимизации времени их исполнения.41 Мы не проводили работ по полному сличению материала статьи с ИТС и фактически имеющихся в базах индексов. Но то, что мы сравнивали, позволяет говорить о том, что это точное и очень полезное описание для версий 8.2 .14–8.3 .5. Как мы говорили, фактический состав индексов надо уметь получать самостоятельно, но в данном материале описаны еще и закономерности, касающиеся разделителей и сплиттера, которые трудно обобщить, анализируя экспериментальные данные.88 Настольная книга 1С:Эксперта по технологическим вопросамСправочник4236Основные индексыИндекс Условие[ОРНР1 + …+] Ссылка(Кластерный)43 Всегда. В индекс входят поля независимых разделителей, которые разделяют этот справочник[ОРРХ | ОРНР1 +] Код + Ссылка Свойство «Длина кода» не равно 0.Если справочник разделяется одним независимым раздели-телем, тип которого не Строка, то индекс содержит поле этого разделителя.Если тип разделителя – Строка, или разделитель независимый и совместный, или разделителей больше одного, то индекс содержит поле значения хеш-функции значений разделителей.Это правило справедливо для всех индексов, в со ставе которых указано [ОРРХ | ОРНР1 +][ОРРХ | ОРНР1 +] Наименование + Ссылка Свойство «Длина наименования» не равно 0[ОРРХ | ОРНР1 +] Реквизит + Ссылка Для реквизита «Реквизит» свойство «Индексировать» установ- лено в значение «Индексировать»[ОРРХ | ОРНР1 +] Реквизит + Код + Ссылка Для реквизита «Реквизит» свойство «Индексировать» установ- лено в значение «Индексировать с доп. Упорядочиванием», и при этом свойство «Длина кода» не равно 0, а свойство «Основное представление» равно «В виде кода»[ОРРХ | ОРНР1 +] Реквизит + Наиме- нование + Ссылка Для реквизита «Реквизит» свойство «Индексировать» установ- лено в значение «Индексировать с доп. упорядочиванием», и при этом свойство «Длина наименования» не равно 0, а свойство «о сновное представление» равно «В виде наимено- вания»[ОРРХ | ОРНР1 +] Реквизит Справочник включен в критерий отбора через реквизит «Реквизит»ДокументИндекс Условие[ОРНР1 + …+] Ссылка (Кластерный) Всегда. В индекс входят поля независимых разделителей, которые разделяют этот документ[ОРРХ | ОРНР1 +] Дата + Ссылка Всегда[ОРРХ | ОРНР1 +] Номер + Ссылка Свойство «Длина номера» не равно 0[ОРРХ | ОРНР1 +] Реквизит + Ссылка Для реквизита «Реквизит» свойство «Индексировать» установлено в значение «Индексировать»[ОРРХ | ОРНР1 +] Реквизит + Дата + Ссылка Для реквизита «Реквизит» свойство «Индексировать» установлено в значение «Индексировать с доп. упорядочи- ванием»[ОРРХ | ОРНР1 +] Реквизит Документ включен в критерий отбора через реквизит «Реквизит»[ОРРХ | ОРНР1 +] ПрефиксНомера + Номер + Ссылка Свойство «Длина номера» не равно 0<…>42 Кластерные индексы выделены полужирным. 43 Для справочников приведены не все индексы, а только наиболее важные для наших целей. Дополнительные индексы для иерархических и подчиненных справочников см. в оригинале статьи.89 ТеорияТабличная частьИндекс Условие[ОРНР1 + …+] Ссылка +Ключ (Кластерный) Всегда. В индекс входят поля независимых разделителей, разделяющих объект, которому принадлежит табличная часть[ОРНР1 + … +] Реквизит + Ссылка Объект конфигурации включен в критерий отбора через реквизит «Реквизит» табличной части, или для реквизита табличной части установлено свойство «Индексировать». В индекс входят поля независимых разделителей, разделяющих объект, которому принадлежит табличная частьДля всех таблиц, которые предоставляют доступ к табличным частям объектов.Регистр сведенийНепериодический регистр сведенийИндекс Условие и описание[ОРРХ | ОРНР1 +] Измерение1 +[Измерение2 +…] (Кластерный) Есть хоть одно измерение регистра. Индекс, включающий все измерения в том порядке, в котором они заданы при конфигурировании.Индекс кластерный, если регистр независимый[ОРРХ | ОРНР1 +] ИзмерениеN + Измерение1 + [Измерение2 +…] Измерению «ИзмерениеN» задано свойство «Индексировать» или свойство «Ведущее», и при этом это не первое и не единственное измерение. Индекс, включающий все измерения. Первое поле – «ИзмерениеN», затем все остальные измерения в том порядке, в котором они заданы при конфигурировании[ОРРХ | ОРНР1 +] Реквизит + Измерение1 + [Измерение2 +…] Реквизиту «Реквизит» задано свойство «Индексировать». Индекс, в котором первое поле – «Реквизит», затем все измерения в том порядке, в котором они заданы при конфигурировании[ОРРХ | ОРНР1 +] SimpleKey44 Количество измерений больше одного. Используется для обхода регистра при реструктуризации, а также для выборки записей с использованием оптимального порядка обхода[ОРРХ | ОРНР1 +] Ресурс + Измерение1 + [Измерение2 +…] Ресурсу «Ресурс» задано свойство «Индексировать». Индекс, в котором первое поле – «Ресурс», затем все измерения в том порядке, в котором они заданы при конфигурированииПериодический регистр сведенийИндекс Условие и описание[ОРРХ | ОРНР1 +] Период + [Измерение1 +…] (Кластерный) (для 8.2)[ОРРХ | ОРНР1 +] [Измерение1 + …] +Период (Кластерный) (для 8.3) Всегда[ОРРХ | ОРНР1 +] Измерение1 + [Измерение2 +…] + Период (для 8.2)[ОРРХ | ОРНР1 +] Период + Измерение1 + [Измерение2 +…] (для 8.3) Есть хоть одно измерение регистра. Индекс, включающий все измерения в том порядке, в котором они заданы при конфигурировании и поле «Период»[ОРРХ | ОРНР1 +] ИзмерениеN + Период + Измерение1 + [Измерение2 +…] Измерению «ИзмерениеN» задано свойство «Индек-сировать» или свойство «Ведущее», и при этом это не единственное измерение. Индекс, включающий поле «Период» и все измерения. Первое поле – «ИзмерениеN», затем поле «Период», затем все остальные измерения в том порядке, в котором они заданы при конфигуриро- вании________________44 SimpleKey – короткий ключ записи регистра. Поле присутствует у непериодических регистров, имеющих хотя бы одно измерение.90 Настольная книга 1С:Эксперта по технологическим вопросамИндекс Условие и описание[ОРРХ | ОРНР1 +] Реквизит + Период + [Измерение1 + …] Реквизиту «Реквизит» задано свойство «Индексиро- вать». Индекс, в котором первое поле – «Реквизит», затем поле «Период», затем все измерения в том порядке, в котором они заданы при конфигурировании[ОРРХ | ОРНР1 +] Ресурс + Период + [Измерение1 + …] Ресурсу «Ресурс» задано свойство «Индексировать». Индекс, в котором первое поле – «Ресурс», затем поле «Период», затем все измерения в том порядке, в котором они заданы при конфигурированииДополнительный индекс для регистра сведений, подчиненного регистраторуИндекс Условие и описание[ОРНР1 + … +] Регистратор + НомерСтроки (Кластерный) Всегда. В индекс входят поля независимых разделителей, которые разделяют этот регистр. Индекс кластерный, если регистр непериодическийРегистр сведений с периодичностью «По позиции регистратора»Индекс Условие и описание[ОРРХ | ОРНР1 +] Период + Реги-стратор + НомерСтроки (Кластерный) Всегда[ОРНР1 + … +] Регистратор + Номер-Строки Всегда. В индекс входят поля независимых разделителей, которые разделяют этот регистр[ОРРХ | ОРНР1 +] Измерение1 + [Изме-рение2 + …] + Период + Регистратор + НомерСтроки Есть хоть одно измерение регистра. Индекс, включающий все измерения в том порядке, в котором они заданы при конфигурировании, поле «Период» и поле «Регистратор»[ОРРХ | ОРНР1 +] Измерение + Период + Регистратор + НомерСтроки Измерению «Измерение» задано свойство «Индексировать»[ОРРХ | ОРНР1 +] Реквизит + Период + Регистратор + НомерСтроки Реквизиту «Реквизит» задано свойство «Индексировать»[ОРРХ | ОРНР1 +] Ресурс + Период + Регистратор + НомерСтроки Ресурсу «Ресурс» задано свойство «Индексировать»Регистр накопления4537Основная таблица регистраИндекс Условие[ОРРХ | ОРНР1 +] Период + Регистратор + НомерСтроки (Кластерный) Всегда[ОРНР1 + … +] Регистратор + НомерСтроки Всегда. В индекс входят поля независимых разделителей, которые разделяют этот регистр[ОРРХ | ОРНР1 +] Измерение + Период + Регистратор + НомерСтроки Измерению «Измерение» задано свойство «Индексиро- вать»[ОРРХ | ОРНР1 +] Реквизит + Период + Регистратор + НомерСтроки Реквизиту «Реквизит» задано свойство «Индексировать»45 Для регистров накопления приведены не все индексы, а только наиболее важные для наших целей. Индексы для таблицы агрегатов, таблицы статистики регистра накопления и пр. см. в оригинале статьи.91 ТеорияТаблица остатковИндекс Условие[ОРРХ | ОРНР1 +] Период + Измерение1 + . .. + ИзмерениеN (Кластерный) ) + Splitter46 Для регистров вида «Остатки»[ОРРХ | ОРНР1 +] Измерение + Период Измерению «Измерение» задано свойство «Индексиро- вать»Таблица оборотовИндекс Условие[ОРРХ | ОРНР1 +] Период + Измерение1 + . .. + ИзмерениеN (Кластерный) + Splitter Для регистров вида «Обороты»[ОРРХ | ОРНР1 +] Измерение + Период Измерению «Измерение» задано свойство «Индексиро- вать»<…>Регистр бухгалтерииОсновная таблица регистра без корреспонденцииИндекс Условие и описание[ОРРХ | ОРНР1 +] Период + Регистратор + НомерСтроки (Кластерный) Всегда[ОРНР1 + … +] Регистратор + НомерСтроки Всегда. В индекс входят поля независимых разделителей, которые разделяют этот регистр[ОРРХ | ОРНР1 +] Счет + Период + Регистратор Регистру назначен план счетов[ОРРХ | ОРНР1 +] Измерение + Период + Регистратор + НомерСтроки Измерению «Измерение» задано свойство «Индексиро- вать»[ОРРХ | ОРНР1 +] Реквизит + Период + Регистратор + НомерСтроки Реквизиту «Реквизит» задано свойство «Индексировать»Основная таблица регистра с корреспонденциейОт вышеприведенного состава индексов отличается лишь тем, что вместо индекса по счету создаются два индекса по счету дебета и счету кредита.Индекс Условие[ОРРХ | ОРНР1 +] СчетДт + Период + Регистратор Регистру назначен план счетов[ОРРХ | ОРНР1 +] СчетКт + Период + Регистратор Регистру назначен план счетовТаблица итогов по счетуИндекс Условие[ОРРХ | ОРНР1 +] Период [+ Счет] + ИзмерениеБезПризнакаУчета1 + … + ДополнительноеИзмерение1 + … + Измере-ниеСПризнакомУчета1 + … [+ ХэшИзмерений] [+ РазделительИтогов47 ] Поле «Счет» добавляется в случае, если регистру определен план счетов.Поле «ХэшИзмерений» добавляется, количество других полей больше 15. Поле «РазделительИтогов» добавляется, если включено разделение итогов________________46 Splitter – указано для регистра накопления. Для регистра бухгалтерии указано «РазделительИтогов». На практике можно убедиться, что поле добавляется в индекс, если для регистра разрешено разделение итогов в конфигураторе (и неважно, включено разделение итогов или нет). 47 См. выше примечание к полю Splitter для регистров накопления.92 Настольная книга 1С:Эксперта по технологическим вопросамТаблица итогов между счетамиТолько для регистров, поддерживающих корреспонденцию.Индекс Условие[ОРРХ | ОРНР1 +] ИзмерениеДт1 + ИзмерениеКт1 + … Измерение1 + … [+ ХэшИзмерений] [+ РазделительИтогов] Для небалансовых измерений.Для балансовых измерений.Поле «ХэшИзмерений» добавляется, количество других полей больше 15.Поле «РазделительИтогов» добавляется, если включено разделение итоговТаблица со значениями субконтоИндекс Условие[ОРРХ | ОРНР1 +] Регистратор + Номер-Строки + Корреспонденция Всегда[ОРРХ | ОРНР1 +] Период + Регистратор + НомерСтроки + ВидСубконто + Корреспон-денция (Кластерный) Всегда[ОРРХ | ОРНР1 +] ВидСубконто + Значение Всегда<…>Важное дополнение по индексам для 8.3 без режима совместимостиПриведенные выше сведения справедливы для 8.2 и для 8.3 в режиме совмести-мости с 8.2 .В 8.3 у периодических регистров кластерный индекс выглядит: Измерение 1 + …. + Период, а не Период + Измерение 1 + …Всегда проверяйте, какие именно индексы созданы для вашей базы.Сравните рис. 3.13.2, 3.13.3, 3.13.4 .Рис. 3.13.2. Кластерный индекс периодического (периодичность –секунда)независимого регистра сведений в 8.293 ТеорияРис. 3.13.3. Он же, если базу открыть в 8.3 и даже отключить режим совместимости(применив изменения). Ничего не изменилосьРис. 3.13.4. Он же после принудительного выполнения реиндексации и реструктуризациичерез режим «Тестирование и исправление»Видно, что структура кластерного индекса периодического регистра сведений поме-нялась: поле Период было первым, стало последним.94 Настольная книга 1С:Эксперта по технологическим вопросам3.14. Планы запросов. Получение плана запросав профайлере SQL. Операторы плана,наиболее важные для насПолучение плана запроса в профайлере SQLПлан выполнения запроса – это последовательность операций, необходимых для получения результата запроса в СУБД. По фактическому плану можно понять, какой именно алгоритм СУБД выбрала для решения поставленной перед ней задачи, какие операторы решила использовать. Проанализировав, как выполнился каждый из операторов, можно определить, не ошиблась ли СУБД в этом выборе.Чтобы получить текст запроса так, как его получает SQL Server, и увидеть план запроса, нужно сделать следующее: 1. Запустить SQL Server Profiler.2. Создать трассировку. Можно использовать стандартный шаблон.3. В свойствах трассировки: □ Убедиться, что в нее входят события SQL:BatchStarted, SQL:BatchCompleted, RPC:Completed. □ Установить галочку «все события». □ Добавить события Showplan Statistics Profile и Showplan XML Statistics Profile48 из узла Performance. 38 □ Снять галочку «все события», останутся только выбранные. □ Установить галочку «все столбцы». □ Добавить столбец «DatabaseName». □ Зайти в «фильтры столбцов», поставить фильтр «DatabaseName» «Похоже на (Like)» <написать_имя_своей_базы>. □ Убедиться, что у события Showplan Statistics Profile включен столбец BinaryData. □ Снять галочку «все столбцы», останутся только выбранные. □ В итоге настройка трассировки как минимум должна содержать все поля, показанные на рис. 3.14.1 .4. Если запрос выполняется из «1С», в конфигураторе «1С» установить один останов на отладчике на строке интересующего нас запроса, и второй – сразу после него. Дойти до первого останова.5. Запустить трассировку.6. Позволить приложению выполнить запрос (если запрос выполняется из «1С», это значит продолжить отладку и дойти до следующего останова на отладчике; если запрос выполняется из SQL Management Studio, это значит запустить его). 48 В узле Performance находятся также другие события Showplan, но по большей части они относятся к ожидаемым планам и не содержат важной для нас информации о фактическом количестве строк и количестве выполнений операторов.95 Теория7. Остановить трассировку в приложении SQL Server Profiler («Паузой», если нужно, чтобы при следующем выполнении трассировки запроса строки, полученные при нынешней трассировке, остались; «Стопом», если нужно, чтобы они очистились). 8. Найти свой запрос в трассировке. Обычно ориентируются по наибольшему значению в поле Duration для событий SQL:BatchCompleted или RPC:Completed, потому что есть основания считать, что именно исследуемый запрос имеет наибольшую длительность. События Showplan Statistics Profile и Showplan XML Statistics Profile, относящиеся к исследуемому запросу, находятся непосредст-венно над ними. 9. Выбрать событие SQL:BatchStarted, SQL:BatchCompleted или RPC:Completed, просмотреть текст запроса так, как его получает SQL Server.10. Выбрать событие Showplan Statistics Profile, просмотреть план запроса, обра-тить внимание на используемые операторы и столбцы Rows (количество строк) и Executes (количество выполнений) для них.3911. Выбрать событие Showplan XML Statistics Profile, просмотреть графический план запроса с помощью всплывающей подсказки (подробности по ней будут ниже)49 .12. При необходимости сохранить трассировку.13. По совокупности полученных показателей сделать вывод об оптимальности выбранного плана. Рис. 3.14.1. Настройка трассировки для получения планов запроса49 В MSDN описан другой способ. Графический план фактического выполнения можно получить так же, выполнив запрос в SQL Management Studio, если включить там опцию «Запрос» – «Включить действительный план выполнения». Текст запроса можно скопировать туда, например, из SQL:BatchCompleted, тогда в конец текста запроса будут включены еще и значения параметров. Этот способ содержит два важных ограничения: он прост только для простых запросов, когда нет временных таблиц, и он не выводит план в текстовом виде с важными для нас столбцами Rows и Executes (как получить из него для SQL Server 2005 количество выполнений каждого оператора, мы так и не нашли). 96 Настольная книга 1С:Эксперта по технологическим вопросамПроиллюстрируем это на примерах. Возьмем демобазу «Бухгалтерии предприятия», редакция 3.0 (3.0 .19.15). Пример 1Выполним из SQL Management Studio следующий запрос, включив трассировку профайлером (_AccRg7172 – это основная таблица регистра бухгалтерии «Хозрас-четный»).SELECT *FROM _AccRg7172План запроса, полученный через Showplan Statistics Profile, будет следующим50:40Rows Executes StmtText—- ——– ——–1181 1 Clustered Index Scan (OBJECT:([unt3].[dbo].[_AccRg7172].[ _AccRg7172_ByPeriod_TRN]))Пример 2Теперь выполним, казалось бы, точно такой же запрос, но уже средствами «1С»: ВЫБРАТЬ *ИЗ РегистрБухгалтерии.Хозрасчетный КАК ХозрасчетныйПлан запроса, полученный через Showplan Statistics Profile, будет следующим:Rows Executes StmtText—- ——– ——–1181 1 Clustered Index Seek (OBJECT:([unt3].[dbo].[ _AccRg7172].[ _AccRg7172_ByPeriod_TRN] AS [T1]),SEEK:([T1].[ _Fld10847]=[@P1]) ORDERED FORWARD)Сразу видим, что в плане используется другой оператор. Посмотрим на текст запроса, как он попадает в RPC:Completed51 . 41exec sp_executesql N’SELECTT1._ Period,T1._ RecorderTRef,T1._ RecorderRRef,T1._ L ineNo,T1._ Active,T1._ AccountDtRRef,T1._ AccountCtRRef,T1._ F ld7173RRef,T1._ F ld7174DtRRef,T1._ F ld7174CtRRef,T1._ F ld7175DtRRef,T1._ F ld7175CtRRef,T1._ F ld7176,T1._ F ld7177Dt,T1._ F ld7177Ct,T1._ F ld7178Dt,T1._ F ld7178Ct,T1._ F ld7179Dt,T1._ F ld7179Ct,50 В примерах планов в этой главе выводятся только первые 3 столбца. На самом деле их больше, но нам сейчас и важны только первые 3. 51 Собственно запрос начинается со слова SELECT.97 ИнструкцииT1._ F ld7180Dt,T1._ F ld7180Ct,T1._ F ld7181Dt,T1._ F ld7181Ct,T1._ F ld7182,T1._ F ld7183FROM _AccRg7172 T1 WITH(NOLOCK)WHERE (T1. _ Fld10847 =@P1)’,N’@P1 numeric(1)’,0То, что «*» заменена на перечень полей, это нормально. Но откуда взялось условие по полю _Fld10847? Понятно, что это из-за него мог быть выбран другой оператор.Когда мы рассматривали структуру хранения базы, то обращали внимание, что через метод ПолучитьСтруктуруХраненияБазыДанных() можно получить не только имена таблиц, но и индексы (правда, как было показано, с некоторыми ограничениями), и имена полей. На рис. 3.14.2 показано, как это сделать для расшифровки полей.98 Настольная книга 1С:Эксперта по технологическим вопросамРис. 3.14.2. Получение структуры полей в терминах метаданных «1С»Теперь, расшифровав имена полей таблицы _AccRg7172, получим, что поле _ Fld10847 – это ОбщийРеквизит.ОбластьДанныхОсновныеДанные. Посмотрев конфи-гурацию, убеждаемся, что этот общий реквизит там действительно есть.Мы таким образом встретились с работой механизма разделения данных там, где этого совсем не ждали. Нам это, впрочем, сейчас не мешает, и просто примем это как данность.Посмотрим теперь на графический план запроса из примера 2, встав в трассировке на Showplan XML Statistics Profile. Наведя курсор на значок оператора, увидим всплывающую подсказку, как это показано на рис. 3.14.3, которая показывает детали для каждого из операторов.Что собой представляет каждая из строк всплывающей подсказки, описано в таблице 3.14 .1. Порядок следования, состав и даже названия этих строк в действитель-ности могут несколько отличаться от примеров, представленных в таблице 3.14.1, например, из-за того, что используется другая версия SQL Server.План запроса состоит из операторов. Фактически план запроса – это дерево физи-ческих операторов.Операторы описывают, как SQL Server выполняет запрос. Оптимизатор запросов использует операторы для построения плана запроса, чтобы создать результат, заданный в запросе. Операторы классифицируются как логические и физические. Логические операторы описывают операции реляционной алгебры, используемые для обработки запроса: описывают концепцию, какие действия надо совершить. Физические операторы реализуют действия, описанные логическими операторами. Каждый физический оператор является объектом или процедурой, выполняющей операцию. Физическим операторам соответствует их стоимость. Оптимизатор строит дерево логических операций, а затем, используя подход, основанный на стоимости, подбирает физические операторы в дерево плана. Обычно логическую операцию можно реализовать несколькими способами, используя разные физические опера-торы. Наоборот, один физический оператор очень редко может реализовывать несколько логических операций. 99 ИнструкцииРис. 3.14.3. Графический план запроса и всплывающая подсказка100 Настольная книга 1С:Эксперта по технологическим вопросамТаблица 3.14 .1. Дополнительная информация о плане запроса,выводимая в том числе в виде всплывающей подсказкиЭлемент всплывающей подсказки(англ. и рус.) ОписаниеPhysical OperationФизическая операция Используемый операторLogical OperationЛогическая операция Логический оператор, который соответствует физическому операторуActual RowsФактическое количество строк Фактическое количество строкEstimated I/O CostПредполагаемая стоимость операций ввода-вывода Приблизительные затраты на выполнение действий ввода-вы -вода для данной операции. С точки зрения СУБД это значение должно быть как можно меньшеEstimated CPU CostПредполагаемая стоимость процесс-ного ресурса Приблизительные затраты на всю работу процессора (CPU) для данной операцииEstimated Operator CostПредполагаемая стоимость оператора Затраты оптимизатора запросов на выполнение этой операции. Затраты на выполнение этой операции в процентном отношении к общим затратам на выполнение запро са отображаются в скобках. С точки зрения СУБД это значение должно быть как можно меньшеEstimated Subtree CostПредполагаемая стоимость поддерева Общие затраты оптимизатора запросов на выполнение этой и всех предшествующих операций в данном поддеревеEstimated Number of Rows Предполагаемое количество строк Ожидаемое количество строк, выдаваемых оператором52Estimated Row SizeПредполагаемый размер строки Предполагаемый размер строки, получаемой на выходе оператора (в байтах)ActualRebindsФактическое число повторных привязок Счетчики указывают на число инициализаций физического оператора (вызовов метода Init()). Физический оператор может получать много вызовов Init(), хотя обычно получает лишь один. Графический план отображает нули для действительных повторных привязок и сбросов на начало, когда те отсут-ствуют ActualRewindsФактическое число сбросов на началоOrderedОтсортировано Отсортировано или нетNode IDИдентификатор узла Номер узла (оператора) в плане текущего запроса________________52 В MSDN сказано (дословно): «Эта всплывающая подсказка выглядит так же, как Количество строк в реальном плане выполнения». В английской версии: «This ToolTip item displays as Number ofRows in an Actual Execution Plan». Если заранее не знать, о чем речь, смысл фразы может быть понят неоднозначно, даже в английском варианте. Мы понимаем эту фразу так: если вы смотрите реальный (действительный) план выполнения, а не ожидаемый, то вам в поле «Ожидаемое количество строк» будет выведено то же самое, что уже есть в поле «Фактическое количество строк». А чтобы узнать, сколько их ожидалось, нужно смотреть ожидаемый план, например, через событие Showplan XML, которое, как и вообще работу с ожидаемыми планами, мы в этой книге не рассматриваем.101 ИнструкцииНаиболее важные для нас операторыДалее рассмотрим наиболее важные для нас операторы, разбитые по способу выпол-нения ими действий. Сканирующие операторыСканирование – это получение всех записей. Разница состоит только в том, что именно проходится: кластерный индекс, некластерный индекс или сама таблица. Просмотрев все записи, сканирующие операторы возвращают ту их часть, которая подходит под условие, если оно задано необязательным предикатом WHERE:(). Детали по таким операторам приведены в таблице 3.14.2 . Пример плана можно посмотреть в этой главе выше (см. пример 1).Таблица 3.14 .2. Сканирующие операторы плана запросаЗначок Название ОписаниеClustered Index Scan Оператор Clustered Index Scan сканирует кластерный индекс, указанный в столбце Argument53 . Clustered Index Scan является логическим и физиче-ским операторомIndex Scan Оператор Index Scan получает все записи некластерного индекса, указанного в столбце Argument. Index Scan является логическим и физическим опера-торомTable Scan Оператор Table Scan получает строки из таблицы, указанной в столбце Argument плана выполнения запроса. Table Scan является логическим и физическим операторомОпасность сканирования состоит в двух вещах: времени выполнения (особенно для Table Scan) и избыточных блокировках. Время выполнения операторов сканирования линейно растет с ростом сканируемых объектов. Сканирование не приводит к избыточным блокировкам в двух случаях: ■ на самом деле нужна вся таблица; ■ сканируется временная таблица; тогда, если посмотреть на объект, будет видно, что она временная:Table Scan OBJECT:([tempdb].[dbo].[#tt3] AS [T2]) [T2].[ _Q_000_F _000RRef], [T2].[_Q_000 _F_001]План запроса может считаться неоптимальным, если в нем встречается оператор сканирования, и при этом: ■ время выполнения оператора очень большое, как в абсолютном, так и в процентном выражении (в книге «Профессиональная разработка…» в качестве заслуживающей внимания называется величина, превышающая 20 % от общего времени);________________53 Здесь и далее: столбец Argument выводится в Showplan Statistics Profile, но из-за большой длины строк мы не имеем возможности приводить его в примерах. Однако, с чем идет работа, можно понять и из столбца StmtText в Showplan Statistics Profile, а в графическом плане – из поля «Объект» («Object»).102 Настольная книга 1С:Эксперта по технологическим вопросам ■ количество строк, возвращаемых оператором, несопоставимо меньше количества строк в таблице; ■ количество строк, возвращаемых оператором, может быть, и не намного меньше количества строк в таблице, но установлено, что конфликты блокировок возни-кают именно из-за избыточного блокирования не используемых на самом деле строк. Особо следует указать оператор Constant Scan. В основном потому, что из-за его имени ему могут приписывать несвойственную ему функциональность. Подробности приведены в таблице 3.14 .3.Таблица 3.14 .3. Оператор Constant ScanЗначок Название ОписаниеConstant Scan Оператор Constant Scan вводит в запрос одну или несколько константных строк. После выполнения оператора Constant Scan часто используется оператор Compute Scalar, который добавляет столбцы в строки, полученные в результате выполнения оператора Constant Scan. Оператор Constant Scan никак не связан с таблицей (таблицами) констант «1С»Операторы поиска по индексуЭти операторы первоначально считывают только строки, найденные по индексу с указанным в предикате SEEK:() условием поиска. Если этого не хватает для полного выполнения условий, может включаться необязательный предикат WHERE:(), в котором подсистема хранилища вычисляет выражение для всех строк, удовлетво-ряющих предикату SEEK:(). Предикат WHERE:() уже не использует индекс. Детали по таким операторам приведены в таблице 3.14.4 . Примеры плана можно посмо-треть в этой главе выше (см. пример 2) и ниже (см. примеры 3 и 4).Таблица 3.14 .4. Операторы плана запроса, использующие поиск по индексуЗначок Название ОписаниеClustered Index Seek Оператор Clustered Index Seek использует поисковые возможности индексов для получения строк из кластерного индекса, указанного в столбце Argument. Clustered Index Seek – это логический и физический операторIndex Seek Оператор Index Seek использует возможности поиска по индексам для получения строк из некластерного индекса, указанного в столбце Argument. Index Seek является логическим и физическим операторомОператор поиска по индексу может приводить к избыточным блокировкам, если в нем есть необязательный предикат WHERE:(), потому что в этом случае все равно блокируются все строки, прочитанные по условию предиката SEEK:(). План запроса может считаться неоптимальным, если в нем встречается оператор поиска по индексу, и при этом: ■ количество строк, возвращаемых оператором по совокупности условий преди-катов SEEK:() и WHERE:(), несопоставимо меньше количества строк, возвращае-мого только по условию предиката SEEK:(), см. пример 4; ■ количество строк, возвращаемых оператором по совокупности условий преди-катов SEEK:() и WHERE:(), может быть и ненамного меньше количества строк, возвращаемого только по условию предиката SEEK:(), но установлено, что 103 Инструкцииконфликты блокировок возникают именно из-за избыточного блокирования не используемых на самом деле строк. Пример 3В той же самой базе «Бухгалтерии предприятия» выполним запрос:ВЫБРАТЬ *ИЗ РегистрБухгалтерии.Хозрасчетный КАК ХозрасчетныйГДЕ Хозрасчетный.Период =&ПериодУ основной таблицы регистра бухгалтерии, с которой мы работаем, есть подхо-дящий54 индекс (Разделитель данных) + Период + Регистратор + НомерСтроки. Все условия могут быть проверены с помощью этого кластерного индекса. План запроса:42Rows Executes StmtText—- ——– ——–17 1 Clustered Index Seek(OBJECT:([unt3].[dbo].[ _AccRg7172].[ _AccRg7172_ByPeriod_TRN] AS [T1]),SEEK:([T1].[ _Fld10847]=[@P1] AND [T1].[ _Period]=[@P2]) ORDERED FORWARD)Пример 4Допишем еще одно условие в запрос:ВЫБРАТЬ *ИЗ РегистрБухгалтерии.Хозрасчетный КАК ХозрасчетныйГДЕ Хозрасчетный.Период =&ПериодИ Хозрасчетный.НомерСтроки = 3″У основной таблицы регистра бухгалтерии, с которой мы работаем, как говорилось выше, есть кластерный индекс (Разделитель данных) + Период + Регистратор + НомерСтроки. Но поля не идут подряд, то есть между ними «вклинивается» поле Регистратор, не участвующее в условии запроса. Поэтому оптимизатор добавляет предикат WHERE:(). План запроса:Rows Executes StmtText—- ——– ——–1 1 Clustered Index Seek (OBJECT:([unt3].[dbo].[ _AccRg7172].[_AccRg7172_ByPeriod_TRN] AS [T1]),SEEK:([T1].[ _Fld10847]=[@P1] AND [T1].[ _Period]=[@P2]), WHERE:([unt3].[dbo].[ _AccRg7172].[ _LineNo] as [T1].[_LineNo]=[@P3]) ORDERED FORWARD)Как было видно из примера 3, по условию из предиката SEEK:() считываются и блокируются 17 строк. Из результатов текущего запроса видно, что по сово-купности условий предикатов SEEK:() и WHERE:() на самом деле нужна только одна строка, то есть запрос приводит к избыточным блокировкам. 17 строк это само по себе не много, но это число может расти. План запроса при этом нельзя считать неоптимальным: видно, что оптимизатор действительно сделал все, что мог, и виноват в избыточных блокировках не план, а автор запроса.54 Подходящим является индекс, удовлетворяющий следующим требованиям: 1. Индекс содержит все поля, перечисленные в условии. 2. Эти поля находятся в самом начале индекса. 3. Эти поля идут подряд, то есть между ними не «вклиниваются» поля, не участвующие в условии запроса. Об этом еще будем говорить в разделе 4.20, посвященном оптимизации запросов.104 Настольная книга 1С:Эксперта по технологическим вопросамОператоры соединенияЭти операторы выполняют логические операции соединения результатов выполнения других операторов, также интерпретируемых как таблицы. Обычно рассматриваются в противопоставлении: Nested Loops (вложенные циклы, вложенные петли) либо любой другой оператор соединения, одним из которых является оператор Merge Join. Детали по этим операторам приведены в таблице 3.14.5 .Таблица 3.14 .5. Операторы соединенияЗначок Название ОписаниеNested Loops Оператор Nested Loops выполняет логические операции внутреннего соеди-нения, левого внешнего соединения, левого полусоединения и антилевого полусоединения55 . Операции соединения вложенных циклов выполняют поиск во внутренней таблице для каждой строки внешней таблицы. Возвра-щается результат выполнения логической операции над любыми строками, удовлетворяющими необязательному предикату в столбце Argument. Nested Loops является физическим операторомMerge Join Оператор Merge Join выполняет внутреннее соединение, левое внешнее соединение, левое полусоединение, левое антиполусоединение, правое внешнее соединение, правое полусоединение, правое антиполусоединение, а также логические операции соединения. В столбце Argument оператор Merge Join содержит предикат MERGE:(), если операция устанавливает соединение «один ко многим», или предикат MANY-TO-MANY MERGE:(), если операция устанавливает соединение «многие ко многим». Столбец Argument содержит также список столбцов, используемых для выполнения операции с разделителями-запятыми. Соединение слиянием особенно эффективно в случаях, когда явной сортировки не требуется, например, когда в базе данных имеется подходящий индекс, Merge Join является физическим операторомNested Loops – самый простой способ соединения таблиц. Затраты на его выпол-нение минимальны. Из-за этого оптимизатор SQL Sever использует этот оператор всегда, когда не может определить, как именно правильнее соединять таблицы. Это может происходить просто по ошибке, но обычно причина все-таки есть. Такой причиной может быть неактуальная статистика. Чаще всего, однако, это не неакту-альная статистика, а ее отсутствие, что всегда имеет место, когда в запросе на языке «1С» используются соединения с вложенными запросами, соединения с виртуаль-ными таблицами, подзапросы в условиях или в условиях соединения.Пример 5В той же самой базе «Бухгалтерии предприятия» выполним запрос: ВЫБРАТЬ *ИЗ РегистрБухгалтерии.Хозрасчетный КАК ХозрасчетныйГДЕ Хозрасчетный.Регистратор В(ВЫБРАТЬ Документ.РеализацияТоваровУслуг.СсылкаИЗ Документ. РеализацияТоваровУслуг)________________55 Непривычные для специалистов по «1С» термины: полусоединение – semi-join возвращает строки только одной из соединяемых таблиц, без выполнения соединения полностью. Антиполусоединение возвращает те строки таблицы, которые не годятся для соединения с другой таблицей; т. е. они в обычном внешнем соединении выдавали бы NULL.105 ИнструкцииВ условии используется подзапрос, поэтому логично ожидать появления оператора Nested Loops. Планы показаны на рисунках 3.14 .4 и 3.14.5 .Рис. 3.14.4. Текстовый план запроса для примера 5 (фрагмент)Рисунок 3.14.5. Графический план запроса для примера 5Недостаток использования оператора Nested Loops заключается в том, что при соеди- нении таблиц запрос к внутренней (в обоих планах ниже расположенной) таблице выполняется столько раз, сколько строк во внешней (выше расположенной). Если речь идет о соединении таблиц, по которым нет статистики, вся работа предостав-лена на волю случая (это на самом деле и произошло в примере), что может прямо явиться причиной критической деградации производительности при выполнении таких запросов. В текстовой форме плана запроса в примере видно, что запрос в самой нижней строчке выполняется 51 раз, при этом он возвращает 51 строку, то есть 1 строку за обращение. Тот самый случай: 51 раз ходить к шкафу, доставая оттуда по листочку. Кроме того, с ростом базы верхняя таблица может становиться все больше, и это является объективным фактором роста вероятности деградации производительности. Пример 6В заключение продемонстрируем, как работает другой способ соединения. Для этого выполним запрос:ВЫБРАТЬ Хозрасчетный.*, ХозрасчетныйСубконто.*ИЗ РегистрБухгалтерии.Хозрасчетный КАК ХозрасчетныйВНУТРЕННЕЕ СОЕДИНЕНИЕРегистрБухгалтерии.Хозрасчетный.Субконто КАК ХозрасчетныйСубконтоПО Хозрасчетный.Период =ХозрасчетныйСубконто.ПериодИ Хозрасчетный.Регистратор =ХозрасчетныйСубконто.РегистраторИ Хозрасчетный.НомерСтроки =ХозрасчетныйСубконто.НомерСтрокиПланы показаны на рис. 3.14 .6 и 3.14.7. Рис. 3.14.6. Текстовый план запроса для примера 6 (фрагмент)106 Настольная книга 1С:Эксперта по технологическим вопросамРис. 3.14.7. Графический план запроса для примера 6Такое соединение работает хорошо, даже несмотря на значительно больший, чем в предыдущих примерах, размер таблиц, с которыми приходится иметь дело, потому что каждый оператор выполняется только по одному разу.3.15. Особенности чтения в объектной моделиСобственно, чтение в объектной технике – это запрос к базе, текст которого гене-рируется платформой. Если, например, выполнять такой запрос в цикле, это будет ничуть не меньшая, а иногда даже более серьезная ошибка, чем выполнение запроса, написанного на языке запросов. У чтения в объектной модели есть три особенности.1. Иногда ставятся управляемые блокировки.2. Иногда чтение происходит в неявной транзакции.3. Считываются все данные. Разберем их по очереди.1. Иногда ставятся управляемые блокировки.Как указано в разделе 3.8 «Сведения о блокировках «1С», платформой устанавли-ваются управляемые разделяемые блокировки при чтении в объектной технике следующих видов объектов: ■ набор записей регистра сведений, ■ набор записей регистра накопления, ■ набор записей регистра бухгалтерии, ■ набор записей регистра расчета, ■ набор записей перерасчета, ■ набор записей последовательности.2. Иногда чтение происходит в неявной транзакции. 43Как указано в разделе. 3.6, чтение в объектной технике объектов, имеющих табличные части56 , будет выполняться в неявной транзакции. Например, запрос 56 Анонсирован отказ от использования транзакций для этих целей в будущем, но есть ожидания, что на многих продуктивных системах еще на какое-то время сохранится существующее положение дел.107 ИнструкцииДокументПроведен =ДокументСсылка.Проведен; выполнится в транзакции, если для документа данного типа в конфигураторе определена табличная часть, но этот же запрос будет выполняться вне транзакции, если табличных частей у документа нет.3. Считываются все данные. Если посмотреть с помощью замера на отладчике, как выполняется следующий код, то можно увидеть, что основное время всегда тратится на выполнение первой строки:ДокументПроведен =ДокументСсылка.Проведен;ДокументДата =ДокументСсылка.Дата;ДокументНомер =ДокументСсылка.Номер;Если пройти код пошагово отладчиком и при этом посмотреть трассировку в профайлере SQL Server, можно увидеть, что запрос (если есть еще и табличная часть, то несколько запросов в транзакции) выполняется только на первой строке, при этом тексты запросов содержат имена всех реквизитов и все табличные части. На второй и на третьей строке запросы к базе уже не выполняются. На практике это приводит к следующему: ■ если реквизит имеет тип ХранилищеЗначения и в конкретном документе хранится файл размером 500 МБ, то при первом чтении любого реквизита этого документа будет происходить считывание этого файла со всеми сопутствующими затратами времени; ■ если объект имеет табличную часть размером в 50 000 строк, то при первом чтении любого реквизита этого документа будет происходить считывание всех реквизитов всех табличных частей со всеми сопутствующими затратами времени; ■ если вы пытаетесь избавиться от запроса в цикле, в топе будет только одна строка (первое получение реквизита), далее топ-строка в отладчике будет пере-ползать с вызова одного реквизита на другой до тех пор, пока вы не избавитесь от получения в цикле всех реквизитов.По совокупности особенностей можно дать как минимум следующие рекомендации:1. Не делать у объектов реквизитов с типом ХранилищеЗначения, особенно не допускать этого в табличных частях. Следует использовать отдельные справоч-ники для установки соответствия ссылки и хранилища, а в реквизитах объектов хранить ссылки.2. Если не получается отказаться от использования запросов к базе из обработ-чиков событий ПриВыводеСтроки и ПриПолученииДанных, то по крайней мере следует получать эти данные запросом на языке запросов, а не через объектную модель. Код увеличится в объеме, но выиграет в скорости и перестанет генери-ровать транзакции. 108 Настольная книга 1С:Эксперта по технологическим вопросам3.16. Работа с SQL Server. Где хранятся временныетаблицы. Где хранятся снимки Snapshotдля уровня изоляции Read Committed Snapshot