Механизм обмена данными платформы 1С:Предприятие 8 основан на объектах конфигурации, которые называются «план обмена». Этот механизм является основным и призван решать следующие задачи: регистрация изменений объектов и обеспечение обмена сообщениями между узлами распределённой информационной системы. Данная статья предполагает, что читатель уже знаком с основными понятиями и имеет опыт использования планов обмена.
Работа с РИБ в рамках данной статьи рассмотрена не будет, так как РИБ полностью основан на описанных в статье механизмах.
Структуры данных.
План обмена на уровне СУБД это таблица, которая имеет название вида «_Node[N]», где N — это внутренний числовой код типа данных 1С:Предприятие 8. В данном случае этот код будет соответствовать плану обмена.
Создадим тестовый план обмена. В конфигураторе 1С (изображение слева) и в SQL Server Management Studio (изображение справа) это будет выглять следующим образом:
Как мы видим по структуре таблицы справа, план обмена очень похож на справочник. Это тоже ссылочный тип данных. Однако, от справочников его отличает то, что он не может иметь групп и быть иерархическим.
Наименование поля | Имя реквизита | Описание поля |
---|---|---|
_IDRRef | Ссылка | Ссылка на узел плана обмена |
_Version | Версия записи таблицы СУБД | |
_Marked | ПометкаУдаления | Пометка удаления |
_Code | Код | Код узла |
_Description | Наименование | Наименование узла |
_SentNo | НомерОтправленного | Номер отправленного сообщения |
_ReceivedNo | НомерПринятого | Номер принятого сообщения |
_PredefinedID | Идентификатор предопределённого элемента |
Следует отметить, что при создании плана обмена, платформа автоматически создаёт предопределённый узел, соответствующий текущей информационной базе, в которой он создаётся. Реквизиты «Код» и «Наименование» по умолчанию имеют пустые значения, их необходимо заполнить самостоятельно. Для того, чтобы убедиться в этом, выполним следующий код в SQL Server Management Studio:
После того, как мы добавили план обмена, необходимо включить в его состав какой-нибудь объект, чтобы начать ослеживать изменения его данных. Включим в наш тестовый план обмена справочник «Номенклатура». После сохранения конфигурации платформа создаёт для этого справочника служебную таблицу регистрации изменений. Такую таблицу платформа создаёт для каждого включённого в план обмена объекта. Если объект включается в состав нескольких планов обмена, то таблица для регистрации изменений на уровне СУБД используется одна и та же.
Структура таблицы «_ReferenceChngR71» справочника «Номенклатура».
Наименование поля | Имя Реквизита | Описание поля |
---|---|---|
_NodeTRef | Узел | Код типа плана обмена, например, у плана обмена «Тестовый» этот код равен значению «69». |
_NodeRRef | Узел | Ссылка на узел плана обмена |
_MessageNo | НомерСообщения | Номер сообщения, в котором данное изменение было выгружено для соответствующего узла плана обмена |
_IDRRef | Ссылка | Ссылка на элемент справочника «Номенклатура», который изменился |
Таким образом, таблица регистрации изменений состоит из трёх обязательных полей и одного и более полей, которые необходимы для поиска изменившихся данных в основной таблице объекта. Для ссылочных типов данных таких, как справочники или документы, достаточно одного поля — «Ссылка». Однако для табличных типов данных, как, например, регистры сведений или регистры накопления, этих полей может быть несколько. Это зависит от установленного для измерений таких объектов свойства «Основной отбор». Более подробно об этом можно прочитать в книге «Профессиональная разработка в системе 1С:Предприятие 8. Издание 2.» на странице 484.
По умолчанию планы обмена используют автоматическую регистрацию изменений объектов, которые включены в их состав. Однако это поведение можно изменить. В таком случае придётся использовать программную (ручную) регистрацию. Отключить авторегистрацию можно так, как это показано на картинке ниже.
Индексы таблиц регистрации изменений.
Для полноты картины приведу здесь информацию об индексах, которые создаёт платформа для таблиц регистрации изменений. Комментировать ничего не буду, так как, по моему и так всё понятно. Их всего два:
1. Ключ + Узел (кластерный).
2. Узел + Номер сообщения + Ключ.
Момент выполнения регистрации изменений.
Интересным является то, в какой момент при записи объекта в информационную базу выполняется регситрация его изменения. Ниже я привожу последовательность возникновения событий, которая возникает при проведении документа. При этом включена автоматическая регистрация изменений для этого документа в плане обмена. При ручной регистрации мы можем вставить код регистрации изменений в любом месте нижеприведёной последовательности событий.
1. Начало транзакции записи документа.
2. ПередЗаписью.
3. ПередЗаписью (подписка на событие).
4. ПриЗаписи.
5. ПриЗаписи (подписка на событие).
6. ОбработкаПроведения.
7. ОбработкаПроведения (подписка на событие).
8. Регистрация изменения объекта во всех планах обмена, в состав которых он входит, а также для всех узлов этих планов обмена.
9. Фиксация транзакции записи документа.
Почему важно понимать в какой момент происходит регистрация изменений? И почему я привёл в пример именно документ? Дело в том, что регистрация изменений выполняется в одной транзакции с записью и проведением документа. Это обеспечивает согласованность этих двух операций: проведения и регистрации. Следовательно, любая логика регистрации изменений влияет на продолжительность этой транзакции, а также на момент выполнения запроса на блокировку записей таблицы регистрации изменений. В высоко нагруженных системах такой запрос часто приводит к ожиданию на блокировках, которые ранее уже наложила, например, процедура выгрузки изменений. Далее в статье я расскажу об этом более подробно.
Регистрация изменений.
Для регистрации изменения выполним следующий код 1С:
Если мы воспользуемся SQL Server Profiler и посмотрим, что происходит при вызове процедуры «ЗарегистрироватьИзменения», то мы увидим следующий код (для удобства восприятия код немного «причёсан»):
Как мы видим, на 2-ом шаге транзакции 1С сразу же пытается наложить эксклюзивную блокировку на запись регистрации изменения элемента справочника «Номенклатура» по соответствующему узлу плана обмена. Кроме этого, предпринимается попытка установить своеобразный флаг, сигнализирующий о том, что это изменение необходимо выгрузить в новом/следующем сообщении обмена. Этим флагом является реквизит «НомерСообщения» (поле «_MessageNo»), значение которого устанавливается равным NULL.
Обратите внимание, что если мы изменим один и тот же объект несколько раз, то запись изменений для этого объекта будет только одна. Это ключевая особенность планов обмена! Фактически это делает такую запись дефицитным ресурсом, за захват которого конкурируют разные транзакции. Если быть более точным, то таким ресурсом является поле «_MessageNo» этой записи.
По сути, если вы знакомы с проблемой блокировок при обновлении таблицы итогов регистров накопления, то здесь вы увидите схожую ситуацию. Ситуация аналогичная таблицам итогов возникает для планов обмена периодически и только в тех случаях, когда происходит выгрузка изменений. Однако, если в случае с регистрами накопления мы можем использовать режим разделения итогов, чтобы распраллелить хотя бы запись в таблицу итогов, то здесь этой возможности нет. Более подробно об этом будет рассказано ниже.
Ещё одним нюансом, который следует учитывать в высоко нагруженных системах, является то, что даже если мы просто перезапишем объект, ничего в нём не изменив, регистрация изменения этого объекта всё-равно будет выполнена. По этому для таких систем, в качестве оптимизации производительности, можно рекомендовать использование ручной регистрации изменений с контролем фактического изменения данных объекта.
Кроме этого очень важно то, что изменение регистрируется для всех узлов плана обмена. То есть если бы в нашем плане обмена было 10 узлов, то изменение одного объекта потребовало бы создания 10 записей, 100 узлов — 100 записей и так далее. И это только для одного изменения. Этот факт тоже важно учитывать.
Просмотр изменений.
Теперь попробуем изменить что-нибудь в нашем справочнике «Номенклатура» и посмотрим как это отразится в таблице регистрации изменений. Для этого можно воспользоваться следующими запросами 1С или T-SQL:
Запрос = Новый Запрос();
Запрос.Текст = "ВЫБРАТЬ * ИЗ Справочник.Номенклатура.Изменения";
SELECT * FROM [_ReferenceChngR71]
Однако, мы ничего не увидим … Дело в том, что регистрация изменений выполняется только в контексте узлов плана обмена. Это ещё одна ключевая особенность этого объекта конфигурации: все изменения регистрируются только в контексте какого-нибудь узла обмена. Поэтому добавляем новый узел в созданный ранее план обмена «Тестовый», и пытаемся изменить что-нибудь в справочнике «Номенклатура» снова. После этого проверяем таблицы изменений ещё раз и видим, что там появились записи.
Удаление регистрации изменений.
Теперь, чтобы удалить регистрацию изменения, выполним такой код 1С:
На этот раз 1С ограничивается одной командой SQL, пытаясь наложить всю ту же самую эксклюзивную блокировку по тому же самому ключу, что в общем-то ожидаемо и вполне нормально:
Запись изменений в сообщение обмена.
Для того, чтобы выгрузить изменения в другой узел распределённой информационной системы, необходимо эти изменения сначала прочитать, а затем записать в сообщение обмена. Механизм обмена сообщениями тесно интегрирован с планами обмена. В данном случае имеется в виду то, что запись сообщения обмена в файл сопровождается изменением реквизита «НомерСообщения» в таблице регистрации изменений объекта и ревизита «НомерОтправленного» в таблице плана обмена для соответствующего узла, для которого выполняется выгрузка данных. Чтобы реализовать всё это необходимо использовать объект «ЗаписьСообщенияОбмена». Именно этот объект позволяет нам управлять номером отправляемого сообщения: получать новый порядковый номер, записывать его в сообщение обмена, в таблицу регистрации изменений и реквизит узла плана обмена.
Чтобы исследовать код, который необходимо выполнить для записи сообщения обмена, я настроил технологический журнал 1С на регистрацию событий TLOCK, EXCP и TTIMEOUT. Эти события позволяют анализировать установление управляемых блокировок и ошибок, связанных с неудачными попытками установить их. Кроме этого я настроил SQL Server Profiler, чтобы посмотреть какие запросы платформа 1С генерирует на уровне СУБД.
Версия платформы 1С:Предприятие 8.3.7.2027. Управляемый режим блокировок.
// 0. Подготавливаем необходимые объекты.
ФайлСообщенияОбмена = "C:exportmessage.xml";
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.ОткрытьФайл(ФайлСообщенияОбмена);
УзелОбмена = ПланыОбмена.Тестовый.НайтиПоНаименованию("Тестовый узел", Истина);
// 1. Создаём объект "ЗаписьСообщенияОбмена".
ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();
// 2. Начинаем запись сообщения для выбранного узла в файл XML.
ЗаписьСообщения.НачатьЗапись(ЗаписьXML, УзелОбмена);
В книге «Профессиональная разработка в системе «1С:Предприятие 8» (издание 2) от 2012 года на странице 491 написано следующее:
При выполнении этого метода сообщению присваивается номер, определяемый как номер предыдущего отправленного сообщения, увеличенный на 1 (информация берётся из узла-получателя). Производится запись в XML-документ заголовка сообщения, а также записывается начало элемента XML, соответствующего телу сообщения. Устанавливается блокировка на запись базы данных, соответствующая узлу плана обмена.
Если посмотреть ТЖ 1С, то там мы не увидим установки блокировки. Значит управляемая блокировка не устанавливается. На уровне СУБД мы увидим обычный запрос, который характерен для вызова метода ссылки «ПолучитьОбъект»:
SELECT
T1._IDRRef,
T1._Version,
T1._Marked,
T1._Code,
T1._Description,
T1._SentNo,
T1._ReceivedNo,
T1._PredefinedID
FROM
dbo._Node69 T1 -- План обмена "Тестовый"
WHERE
T1._IDRRef = 0x9BD9408D5C93CC8E11E6A9E8C5C37A96 -- Узел обмена "Тестовый узел"
Постольку поскольку наша конфигурация находится в режиме управляемых блокировок, то такой запрос не является блокирующим. Блокировок нет. В книге ошибка? Давайте попробуем зарегистрировать какое-нибудь изменение по нашему узлу. Воспользуемся кодом из раздела «Регистрация изменений». Но сначала убедимся, что изменение уже есть, выполнив код SQL:
Получается в данный момент мы пытаемся выгрузить сообщение, которое ранее уже выгружалось под номером 13. Повторная выгрузка. В данный момент первая сессия 1С остановлена в точке останова после выполнения метода «НачатьЗапись». Теперь откроем вторую сессию 1С и попробуем зарегистрировать изменение этого объекта ещё раз в тот момент как оно отправляется:
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, СсылкаДляОбмена);
Теперь проверим, что изменилось:
Ошибок блокировки не было. Поле «_MessageNo» изменилось, сигнализируя нам, что его необходимо выгрузить. Так какая же блокировка имелась ввиду в книге? Неужели всё-таки ошибка? Ошибки никакой нет. Чтобы убедиться в этом выполним в сессии № 2 следующий код 1С:
Узел = ПланыОбмена.Тестовый.НайтиПоНаименованию("Тестовый узел", Истина);
Объект = Узел.ПолучитьОбъект();
Объект.Заблокировать();
В результате мы получим следующее сообщение об ошибке (эту же ошибку мы увидим в ТЖ, событие EXCP):
{ВнешняяОбработка.ИсследованиеПлановОбмена.МодульОбъекта(103)}: Ошибка при вызове метода контекста (Заблокировать): Не удалось заблокировать запись. Действие (изменение, удаление или блокировка записи) не выполнено.
Ошибка блокировки объекта. Объект уже заблокирован:
компьютер: Zhichkin, сеанс: 45, начат: 24.11.2023 в 1:00:46, приложение: Толстый клиент
Получается, что автор книги имел в виду объектную блокировку узла, а не блокировку записи базы данных. Следовательно, для того, чтобы убедиться в том, что выполняется выгрузка изменений по узлу, необходимо выполнить выше приведённый код и, если возникнет ошибка блокировки, то значит так оно и есть. Посмотрим что будет происходить дальше:
// 3. Выбираем изменения для выгрузки
Выборка = ПланыОбмена.ВыбратьИзменения(УзелОбмена, ЗаписьСообщения.НомерСообщения);
BEGIN TRANSACTION
UPDATE
[_ReferenceChngR71] -- Таблица регистрации изменений
SET
[_MessageNo] = 26 -- Очередной номер отправленного сообщения
WHERE
[_NodeTRef] = 0x00000045 -- План обмена "Тестовый"
AND
[_NodeRRef] = 0x9BD9408D5C93CC8E11E6A9E8C5C37A96 -- Узел "Тестовый узел"
AND
[_MessageNo] IS NULL -- Устанавливаем номер для ещё не отправленных сообщений
-- Выбираем все изменения, в том числе отправленные в других сообщениях
SELECT
[_IDRRef]
FROM
[_ReferenceChngR71]
WHERE
[_NodeTRef] = 0x00000045
AND
[_NodeRRef] = 0x9BD9408D5C93CC8E11E6A9E8C5C37A96
COMMIT TRANSACTION
Этот код будет выполнен для всех типов объектов, которые включены в состав плана обмена. Каждый тип в своей собственной транзакции. На время транзакции будет установлена эксклюзивная транзакционная блокировка SQL Server на все записи узла, которые ещё не отправлялись. Это означает, что повторное изменение уже заблокированных объектов будет ожидать окончания этой транзакции, а, в случае превышения времени ожидания, будет сгенерировано сообщение об ошибке:
При этом если мы зарегистрируем по этому узлу и типу объекта новое изменение, то оно успешно запишется. Более того, если это произойдёт до команды SELECT, то в выборку изменений попадут и эти новые изменения. Что интересно номер отправленного у них будет равен NULL, хотя это совершенно не так.
Кроме этого если записей будет более 5000, то может произойти эскалация блокировок SQL Server. В таком случае может оказаться заблокированной вся таблица. Чтобы этого не происходило, администраторы баз данных часто отключают на уровне SQL возможность возникновения такой эскалации, однако это не запрещает эскалации до уровня страниц (имеют размер 8 Kb), что может приводить к избыточной блокировке записей не попадающих в условия отбора команды UPDATE, но находящихся на одной странице вместе с нужными записями.
Таким образом к негативным последствиям выполнения операции выборки изменений можно отнести следующие:
1. Конфликт блокировок при одновременной работе пользователей и выгрузки изменений. Это может происходить, например, при частом перепроведении одних и тех же документов. При этом следует иметь в виду, что, чем больше изменений накопилось к моменту выгрузки, тем дольше выполняется транзакция и тем выше вероятность возникновения блокировок. В высоко нагруженных информационных системах это обстоятельство может приводить к большим проблемам.
2. Избыточные блокировки при больших объёмах изменений из-за эскалации блокировок SQL Server. Усугубляет последствия первого пункта.
3. Рассогласованность нумерации сообщений для новых регистраций объектов, которые не попали в первоначальный UPDATE. Следствием этого может быть повторная выгрузка одних и тех же данных.
Все выбранные изменения обрабатываются в оперативной памяти. Это происходит в следующем цикле:
// 4. Обработка выбранных изменений
Пока Выборка.Следующий() Цикл
Данные = Выборка.Получить();
ЗаписатьXML(ЗаписьXML, Данные);
КонецЦикла;
На этом этапе на уровне SQLServer ничего интересного не происходит: выполнение метода Выборка.Получить() получает данные объекта по его ссылке так, как если бы мы вызвали метод Ссылка.ПолучитьОбъект() или Набор.Прочитать(). Единственным недостатком можно назвать то, что это выполняется в цикле для каждого объекта, что трудно назвать оптимальным решением. Каждый объект записывается в сообщение обмена в формате XML. Это самый длительный этап выгрузки данных. К сожалению его практически невозможно распараллелить, так как запись ведётся в один файл.
В случае успешной записи сообщения обмена, завершаем сеанс выгрузки данных:
// 5. Завершаем сеанс выгрузки данных
ЗаписьСообщения.ЗакончитьЗапись();
UPDATE
[_Node69] -- План обмена "Тестовый"
SET
[_Marked] = 0x00,
[_Code] = N'1',
[_Description] = N'Тестовый узел',
[_SentNo] = 26, -- Номер только что отправленного сообщения обмена
[_ReceivedNo] = 0,
[_PredefinedID] = 0x00000000000000000000000000000000
WHERE
[_IDRRef] = 0x9BD9408D5C93CC8E11E6A9E8C5C37A96 -- Узел "Тестовый узел"
AND
[_Version] = 0x00000000000077E8
Завершение сеанса выгрузки заключается в том, что для соответствующего узла плана обмена записывается номер только что отправленного сообщения обмена и вызывается метод объекта «Записать». В результате этого на узел плана обмена устанавливается управляемая блокировка — в техническом журнале 1С фиксируется событие TLOCK. Это очень короткая транзакция.
Чтение изменений из сообщения обмена.
Чтение изменений выполняется аналогичным записи сообщения образом. Важной отличительной особенностью является то, что вместо обновления номера отправленного сообщения выполняется удаление регистрации изменений для узла, от которого приняли сообщение обмена. Это нужно только в том случае, если обмен двунаправленный. В противном случае это не нужно. Кроме этого при завершении чтения сообщения обновляется не номер отправлденного сообщения узла плана обмена, а номер принятого. Пример кода загрузки сообщения обмена выглядит следующим образом:
ЧтениеXML = Новый ЧтениеXML();
ЧтениеXML.ОткрытьФайл(ПолноеИмяФайла);
ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();
ЧтениеСообщения.НачатьЧтение(ЧтениеXML, ДопустимыйНомерСообщения.Больший);
Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл
Данные = ПрочитатьXML(ЧтениеXML);
Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель;
Данные.ОбменДанными.Загрузка = Истина;
Данные.Записать();
КонецЦикла;
//ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);
ЧтениеСообщения.ЗакончитьЧтение();
Заключение.
Плюсы планов обмена:
1. Простота программирования и настройки.
Минусы планов обмена:
1. Избыточные блокировки данных.
2. Конфликты блокировок транзакций.
3. Регистрация одного изменения для каждого узла. На мой взгляд это избыточно, а кроме того интегрирует логику маршрутизации сообщений в подсистему регистрации изменений. Нарушается архитектурный принцип разделения ответственности между программными компонентами.
4. Гранулярность обработки данных — узел обмена.
5. Дублирование выгрузки данных.
6. Плохие возможности для распараллеливания процессов.
7. Тесная интеграция механизма регистрации изменений и инфраструктуры сообщений (их нумерация) диктует свои правила и ограничивает возможности реализации каких-то своих оптимизационных решений. См. также пункт 3.
Ошибка блокировки объекта при выполнении автоматического обмена |
Я |
21.08.12 — 11:50
Настроен автоматический обмен между конфигурациями УПП (серверный вариант) и Кортес: адресный склад (файловый вариант). С некоторых пор при выгрузке в Кортес стала вылетать ошибка:
Ошибка при выгрузке данных: {Обработка.ОбменДаннымиXML.МодульОбъекта(12114)}: Ошибка при вызове метода контекста (НачатьЗапись): Не удалось заблокировать запись. Действие (изменение, удаление или блокировка записи) не выполнено.
Ошибка блокировки объекта. Объект уже заблокирован:
сеанс: 1850, начат: 21.08.2012 в 14:39:34, приложение: Фоновое задание
Обмен данными по настройке «Обмен с «Кортес:Адресный склад»» завершен (14:39:35).
А в консоли сервера появляется какое-то фоновое задание.
При этом в настройке базы УПП на сервере 1С предприятия блокировка регламентных заданий отключена. В чем может быть проблема? Заранее благодарен.
1 — 22.08.12 — 10:25
up
2 — 22.08.12 — 10:26
какое то фоновое задание видимо трогает объекты которые пытаешся загрузить. включи блокировку фоновых и сделай обмен
3 — 22.08.12 — 10:41
(2) А где она отключается? В свойствах базы на сервере 1С предприятия тока регламентированные задания отключаются. Мож я не там сиотрю?
4 — 22.08.12 — 10:42
(3) ну вот регл задания и отключи на время
5 — 22.08.12 — 12:03
(4) фоновое выскакивать перестало, но и автообмен не работает никак…
6 — 22.08.12 — 12:04
(5) естественно.
я не понял что надо, если отключил фоновые — сделай обмен в ручную
7 — 22.08.12 — 12:09
(6) вручную проходит без проблем. Но хочется чтобы снова заработал автообмен, который до недавнего времени отлично работал. Фоновое задание мешало как автообмену, так и обмену ручному. После отключения регламентных заданий фоновое лезть перестало, но и перестал работать автообмен. Как все настроить обратно, чтобы снова автообмен заработал? вот в чем вопрос.
8 — 22.08.12 — 12:11
предлагаю сначала выяснить какое фоновое задание маешало, что оно делает. может не нужно впринципе и выключить его нафиг
9 — 22.08.12 — 12:18
Дело в том, что оно какое-то безымянное, возникает скорей всего при автообмене, но отрабатывает коряво, блокируя объект и не освобождая эту блокировку. В консоли у него нет не имени компьютера, ни пользователя.
10 — 22.08.12 — 12:19
(9) ни у каких фоновых нет таких данных. посмотри какие вобще регл задания работают в базе
11 — 22.08.12 — 12:41
(10) да по сути только автообмен…
12 — 22.08.12 — 12:48
(11) не только, раз атообмену мешает фоновое. обработка на ИТС есть, консоль заданий, там погляди какие задания активны
akhmadey
13 — 22.08.12 — 13:54
Если верить обработке, то это фоновое задание и есть автообмен
Вы попали на нужную страницу – мы консультируем по вопросам 1С:Предприятие! Скорее всего, утром вы обнаружили, что любимая 1С 8.3 не запускается с сообщением: «Начало сеанса с информационной базой запрещено. Для выполнения резервного копирования…».
Если вы далеки от технической стороны работы с конфигурацией, обратитесь к нашим специалистам за устранением блокировок 1С. Но если вы решили справиться с проблемой самостоятельно, первое, что сейчас нужно сделать — срочно разрешить работу пользователям. После этого спокойно дочитайте статью до конца и узнайте, почему так произошло и что такое «Блокировка и снятие блокировки с информационной базы 1С 8.3».
Приглашаем на
бесплатный вебинар!
06 июня в 11:00 мск
1 час
Мой опыт подсказывает, что вы – пользователь (не системный администратор и не программист*), а ваша информационная база – файловая (если база SQL, вашей проблемой уже занимаются специалисты). Для начала надо понять, в какой папке (каталоге) она расположена и удалить в этой папке один файл — 1Сv8.cdn (файл можно не сохранять, он больше не понадобится).
*Если вы ИТ-специалист, можете смело переходить к чтению раздела «Блокировка и снятие блокировки с информационной базы 1С».
В окне со списком информационных баз найдите свою базу (цифра 1 на иллюстрации ниже) и нажмите на нее один (и только один!) раз мышкой. Затем нажмите кнопку «Изменить» (цифра 2).
В списке может быть только одна база, поэтому это окно вам может быть знакомо как «окно запуска 1С». В этом случае просто нажмите кнопку «Изменить».
Если вы видите, что информационная база расположена на данном компьютере или в локальной сети — мой опыт не подвел – база файловая, и мы все делаем правильно. Скопируйте этот путь (цифры 3 и 4).
Теперь зайдите в эту папку.
На всякий случай, вот несколько вариантов запуска Проводника:
- У вас Windows XP или Windows 7. Нажмите Пуск, Выполнить, вставьте ранее скопированное расположение информационной базы. Откроется Проводник.
- У вас Windows 7. Но пункта «Выполнить» нет. Вставляйте расположение сразу после нажатия Пуск. Откроется Проводник.
- У вас Windows 8 или Windows 10. Нажмите Пуск, в правом верхнем углу нажмите на Лупу, вставьте ранее скопированное расположение информационной базы, нажмите Enter. Откроется Проводник.
- Найдите на панели задач желтую дискету и нажмите на нее. Вставьте расположение информационной базы в адресную строку в верхней части окна Проводника. (Правой кнопкой мыши на адресную строку, Изменить адрес, правой кнопкой еще раз на адресную строку, Вставить).
- Универсальный способ для всех версий Windows и ее настроек. Нажмите на клавиатуре кнопку с флажком и, не отпуская ее, нажмите на клавиатуре латинскую R (или русскую К). Откроется окно «Выполнить», вставьте туда ранее скопированное расположение информационной базы и нажмите ОК.
Воспользовавшись одним из предложенных вариантов, вы попадете в окно проводника с расположением информационной базы.
В окне проводника найдите в списке файлов файл 1Сv8.cdn, нажмите на нем правой кнопкой мыши, выберите «Удалить», как показано на предыдущем рисунке.
Готово! Ваша «1С:Бухгалтерия» или «1С:Зарплата и управление персоналом» или «1С:Управление торговлей» снова запускаются.
Блокировка и снятие блокировки с информационной базы 1С. Разрушаем мифы.
В данном разделе вы найдете уникальную информацию по работе с блокировками, а также получите опровержение распространенных заблуждений на тему устранения блокировок.
Как установить блокировку?
Механизм блокировки информационной базы предназначен для завершения текущих открытых сеансов и предотвращения новых подключений. Расположение функционала блокировки в меню может различаться в зависимости от конфигурации. Например, в УТ, редакция 11 (11.3.3.163) это НСИ и администрирование, [Сервис] Блокировка работы пользователей. Альтернативный вариант: НСИ и администрирование, Поддержка и обслуживание, Блокировка работы пользователей. В УТ, редакция 10.3 (10.3.21.2) это Сервис, Пользователи, Блокировка установки соединений с информационной базой.
*Существуют специальные отраслевые конфигурации, в которых блокировка с точки зрения интерфейса и с точки зрения механизма будет выглядеть не так, как описано в данной статье. Поскольку мы рассматриваем стандартный механизм для большинства конфигураций 1С, специальные отраслевые конфигурации затрагивать не будем.
При выборе данного пункта откроется диалоговое окно «Блокировка работы пользователей», в котором необходимо ввести сообщение для пользователей, время начала и завершения блокировки, а также код для разблокировки.
Поскольку вводится начало и окончание действия блокировки, необходимо быть крайне внимательным в этом диалоге и ввести информацию в явном виде. Если бы в диалоге была бы возможность ввести начало блокировки «через 15 минут» длительностью «на 20 минут», или хотя бы справочно отображались эти величины на основании абсолютного времени начала и окончания блокировки, то было бы сложно установить блокировку длительностью в год, как это может случиться при ошибке ввода даты-времени.
Параметр «Время начала» рекомендуется установить как текущая дата/время + время, необходимое пользователям на подготовку к выходу с сохранением редактируемых документов. Например, сейчас 9 ч 50 мин, даем 10 минут пользователям для сохранения их результатов. Итого время начала блокировки должно быть 10 ч 00 мин.
Время конца – можно не вводить, при этом блокировка объекта будет установлена бессрочно (навечно).
Код для разблокировки – однократный «пароль» на запуск «с нуля», вопреки установленной блокировке, который может понадобиться в некоторых случаях (будет сказано далее). Вводить и запоминать обязательно. Этот параметр в случае SQL-варианта информационной базы виден в оснастке «Администрирование серверов 1С предприятия» и называется там «Код разрешения».
В случае SQL-варианта информационной базы дополнительно потребуется авторизация администратора информационной базы или администратора кластера.
Итак, после нажатия кнопки «Установить блокировку» и положительного ответа на подтверждение…
…вы вернетесь в предыдущее диалоговое окно, внешний вид которого изменился:
В правом нижнем углу будет выдано сообщение о том, что запланирована блокировка работы пользователей. Данное сообщение увидите только вы.
Запланирована? Быть может это как-то связано с регламентными заданиями?
Сработает ли запланированная блокировка работы пользователей, если установлена блокировка регламентных заданий? Да, сработает. Механизм блокировки не использует регламентные задания.
Что увидят пользователи и я сам?
До момента начала блокировки активные пользователи будут получать «вежливые» напоминания о необходимости завершения работы. В данном диалоге по таймауту срабатывает «Да», поэтому отсутствующие на рабочем месте пользователи успешно выйдут из сеанса 1С.
Инициатор блокировки получает другое сообщение:
После начала действия блокировки в информационную базу нельзя будет зайти обычным способом. О том, как все-таки зайти, будет рассказано ниже. Обратите внимание, что диалог не содержит автоматического указания на время завершения блокировки, поэтому задача проинформировать пользователей о времени возобновления работы ложится на Администратора. Эту информацию можно указать в сообщении пользователю.
Бомба взрывается точно в назначенное время. Сирена воет до взрыва.
Вопреки распространенному мнению, что завершение сеансов активных пользователей производится мягко, после предупреждения, которое можно игнорировать и продолжить работу, на самом деле завершение, а лучше сказать, «обрубание», активных сеансов происходит точно по расписанию, жестко и с потерей всех несохраненных результатов. Все предупреждения выдаются в интервале от времени нажатия кнопки «Установить блокировку» до времени начала блокировки, после наступления которого, завершение активного сеанса произойдет без какого-либо уведомления, а 1С перейдет в цикл попыток запуска конфигурации заново, с интервалом в 1 минуту.
Не составляют исключения режимы ввода справочных значений, при которых введено значение, отсутствующее в справочнике – выйти из режима ввода нельзя (например, закрыть 1С крестиком), но это не помешает завершить работу. Более значительный интерес представляет режим модального диалога, поэтому о нем будет сказано подробнее.
*Завершение сеансов пользователей в старых конфигурациях происходит чуть позже назначенного времени, т.к. пользователи сначала получают оповещение «Работа системы завершается».
А точно взорвется?
Для начала отметим, что в старых конфигурациях может не сработать блокировка для инициатора блокировки. А теперь перейдем к рассмотрению вопроса для платформы 8.3.
Пользователь файловой ИБ, решивший, например, удалить документ, а затем пойти на обед, оставив на экране диалог «Пометить документ на удаление?», будет держать открытым соединение с информационной базой. Конечно, его сеанс завершится после обеда, после того, как он ответит «Да» или «Нет», но до этого момента вы будете видеть, что есть активные пользователи. При этом инициатор блокировки увидит сообщение:
В журнале регистрации появится сообщение о runtime-ошибке, которое следует интерпретировать не как runtime-ошибку, а как «не все пользователи завершили свои сеансы»:
И это не единственная причина, по которой блокировка может не сработать (cм. далее разделы «По чьим часам?» и «А как же мои пользователи во Владивостоке?»).
Модальный диалог в SQL-варианте информационной базы на управляемых формах
Сервер приложений 1С имеет возможность удалить сеанс несмотря на режим модального диалога. Интерфейс 1С и модальный диалог останутся у пользователя на экране, создавая видимость незавершенного сеанса, но на самом деле сеанс будет удален, а соединение с ИБ будет своевременно разорвано. При попытке продолжить работу пользователь увидит сообщение об ошибке «Сеанс отсутствует или удален» или «Сеанс работы завершен Администратором» в зависимости от нюансов.
Модальный диалог в SQL-варианте информационной базы на обычных формах
Сеансы пользователей завершаются.
После установки блокировки из диалога лучше не выходить, т.к. при повторном входе в этот диалог до начала блокировки всплывает не соответствующее действительности сообщение о том, что блокировка уже установлена (правда только наполовину), активных сеансов ноль (неправда). При этом продолжается процесс завершения работы пользователей (противоречит нулю активных сеансов + не совсем так, т.к. пользователи «сами себя завершают»). Хотя код блокировки работы пользователей не идеален, в конце концов, это не помешает установить блокировку и завершить активные сеансы, однако дезориентирует Администратора информационной базы.
Сработает ли блокировка, если установить блокировку и закрыть диалог?
Да
Сработает ли блокировка, если установить блокировку и сразу выйти из 1С (т.е. завершить сеанс 1С до начала действия блокировки)?
Да. Механизм реагирования на установленную блокировку не предусматривает взаимодействия между инициатором блокировки и остальными пользователями. Сеансы пользователей самостоятельно проверяют, можно ли им работать.
По чьим часам сработает блокировка, если время на компьютерах немного отличается?
Проблема рассинхронизации часов
При файловой ИБ каждый компьютер сам проверяет, имеется ли в ИБ установленный временной диапазон блокировки, и сравнивает его со своими локальными часами. От точности своих часов зависит, сможет ли данный компьютер осуществить завершение сеанса точно в нужное время. Если база блокируется с 10:00, для одного компьютера этот момент наступит раньше, а для другого – позже.
В доменной среде и при безупречной работе системных администраторов время на всех компьютерах синхронизируется с контроллером домена. Но по разным причинам время может быть сбито: не настроена синхронизация времени с контроллером домена, настроена синхронизация времени с внешним сервером точного времени, который более недоступен, сбои в работе сетевых или доменных служб, отсутствие прав на изменение системного времени и т.д.
Кажется, что речь может идти о секундах, в крайнем случае, минутах. Но на самом деле, на компьютере может быть, например, не установлено обновление операционной системы, поддерживающее переход на сезонное (зимнее/летнее) время, и ошибка уже может составлять не секунды, а часы. Легко провести такой эксперимент: запланируйте блокировку на 10 утра длительностью полчаса, а на одном из компьютеров переведите время на час вперед – блокировка на него не подействует.
Поэтому перед установкой блокировки внимательно сверьте время в правом нижнем углу компьютера со своими наручными часами, а также заблаговременно обратитесь к своему системному администратору с вопросом, работает ли синхронизация времени в вашей ИТ-инфраструктуре.
А как же мои пользователи во Владивостоке?
Проблема абсолютного времени при пользователях из разных часовых поясов
Временной диапазон блокировки сохраняется в информационной базе. Посмотрите на содержимое блокировочного файла 1Сv8.cdn (который создается в файловом варианте ИБ), в нем записано время начала блокировки 17.07.2017 13:59 в формате ГГГГММДДЧЧММСС без какого-либо указания на часовой пояс:
Без указания на часовой пояс было бы понятно, о каком абсолютном времени идет речь, если время всегда относилось бы к какому-то конкретному часовому поясу, например UTC+0. Но в базе сохраняется локальное время по часам компьютера, который являлся инициатором блокировки. Из какого часового пояса был этот компьютер – неизвестно, а значит неизвестно абсолютное время блокировки.
Если в Москве, в централизованной ИБ, вы устанавливаете блокировку в 13:59, и этот момент времени для московских пользователей находится в будущем, то у пользователей этой же ИБ во Владивостоке 13:59 было 7 часов назад. И в зависимости от технического решения, в соответствии с которым осуществляется работа с ИБ пользователей Владивостока, блокировка этих пользователей либо сработает, либо нет.
Какие могут быть технические решения, в которых блокировка будет работать неправильно для пользователей Владивостока? Те, при которых клиентская часть 1С получит время по Владивостоку, а не по Москве. Например, офисы связаны в локальную сеть по VPN, а клиентская часть 1С запускается с локального компьютера, имея время UTC+10. Но если они работают с базой через RDP-соединение или в режиме RemoteApp на московском сервере, запуская на этом сервере клиентскую часть 1С – все будет хорошо, т.к. она будет иметь время UTC+3.
Имеется ли проблемы рассинхронизации часов и часового пояса в случае SQL-варианта информационной базы?
Нет. В данном варианте есть «часы сервера», которые принимаются за эталон.
Выкинет ли меня из Конфигуратора, если я был в нем, а блокировка начала действовать?
Нет.
Можно ли будет зайти в Конфигуратор после начала действия блокировки?
Нельзя! Проверка возможности работы с конфигуратором выполняется только при запуске и не выполняется в процессе работы. Поэтому, если блокировка устанавливается для последующей работы в конфигураторе, гораздо легче предварительно его запустить, чем потом обходить запрет на запуск.
Как снять блокировку?
В том же диалоге, в котором блокировка устанавливалась. Напоминаем, что после установки блокировки в нем вместо кнопки «Установить блокировку» кнопка «Снять блокировку».
В случае SQL-варианта ИБ снятие блокировки возможно также в оснастке «Администрирование серверов предприятия 1С». (см. далее)
Для чего нужен код разблокировки?
Для входа в ИБ в тот момент, когда действует блокировка. Ситуации, в которых это необходимо:
- После установки блокировки был завершен сеанс работы с ИБ (вручную или в результате действия блокировки на самого инициатора), и требуется начать новый сеанс;
- Время окончания блокировки по ошибке было не заполнено вообще;
- Время окончания блокировки было заполнено ошибочно (например, был нечаянно введен следующий месяц или год);
- Информационная база в SQL-варианте, и для отмены неверно установленной блокировки невозможно удалить файл 1Сv8.cdn в каталоге информационной базы.
В таком случае воспользуйтесь подсказкой, которая дается при запуске. Т.е. в окне со списком информационных баз нажмите «Изменить» и введите в дополнительные параметры запуска строку:
ENTERPRISE /F»Z:ОбменУТ 11″ /CРазрешитьРаботуПользователей /UC12345
… с учетом каталога расположения и кода разблокировки.
Данную строку лучше скопировать в буфер обмена и подправить в диалоге «Редактирование информационной базы». Если вы перепутали тип кавычек или русскую «С» и латинскую, то увидите сообщение об ошибке:
В случае правильного ввода и последующего запуска 1С в режиме предприятия, 1С автоматически снимет блокировку и завершит свою работу. После этого можно будет удалить дополнительные параметры и запускать 1С как обычно.
Что делать, если я не устанавливал блокировку, а SQL-база кем-то заблокирована? При этом я не знаю код разблокировки.
Блокировка информационной базы может устанавливаться самой конфигурацией на время создания архивной копии. Если процесс ее создания не был завершен нормально, SQL-база может остаться в состоянии блокировки. В этом случае необходим доступ к консоли (более правильно – оснастке) «Администрирование серверов 1С:Предприятия».
Где ее искать?
Оснастка «Администрирование серверов 1С:Предприятия» часто установлена на том же сервере, где развернут SQL server, а также где развернут сам «Сервер 1С» (или «Сервер приложений 1С»). Хотя это и не обязательно: SQL может быть установлен на одном компьютере, «Сервер приложений 1С» – на другом, а оснастку можно развернуть и на своей рабочей станции. С большой вероятностью успеха можно достигнуть, сделав следующее:
- Подключитесь по RDP к серверу, который указан в строке Srvr=… используя свой доменный логин и пароль. При невозможности подключения попросите системного администратора добавить вас в группу пользователей удаленного рабочего стола. (В случае отказа в таких правах – разверните и настройте на рабочей станции оснастку «Администрирование серверов предприятия 1С»);
- На сервере найдите оснастку «Администрирование серверов 1С:Предприятия»;
- Запустите оснастку, разверните дерево до узла с вашей информационной базой;
- В свойствах информационной базы снимите чекбокс «Блокировка начала сеансов включена» или исправьте время начала и конца блокировки или посмотрите «код разрешения» для входа в ИБ (он же «код для разблокировки» в диалоге установки блокировки).
Что делать, если все пользователи информационной базы SQL вышли, а запустить Конфигуратор по-прежнему нельзя, т.к. имеются активные пользователи?
В узле «Соединения» информационной базы, в правой части экрана можно удалить имеющиеся соединения.
Это далеко не все вопросы, связанные с темой блокировки информационной базы.
Если у вас остались вопросы:
- Можно ли работать по московскому времени, если вы арендуете сервер в Европе и не хотите зависеть от его часового пояса?
- Как найти Сервер приложений 1С, если неизвестно, где он установлен?
- Как развернуть оснастку «Администрирование серверов 1С:Предприятия» и как ее настроить?
- Если в одной локальной сети несколько серверов приложений, как быть?
- Как быть в случае кластерной системы? и т.д.
… наши сертифицированные консультанты по технологическим вопросам 1С с удовольствием на них ответят и предоставят консультации по вопросам 1С:Предприятие.
В этой статье мы рассмотрим одну из распространённых ошибок в 1С, которая характеризуется появлением сообщения «Ошибка исключительной блокировки информационной базы». Вы узнаете, как можно быстро это исправить и продолжить пользоваться программой.
1С является незаменимым помощником в большинстве организаций — от небольшого офиса до крупной корпорации. Данная программа охватывает множество структур бизнеса и значительно упрощает работу сотрудникам. Но для того чтобы эффективно пользоваться этим инструментом, нужно иметь опыт и умение решать проблемы и ошибки.
Появление ошибок в 1С является нормальным рабочим процессом. Но это не из-за того, что программа как-то плохо сделана. Большинство ошибок возникает от того, что пользователь что-то недоглядел или пропустил. Поэтому важно уметь быстро и оперативно диагностировать и решать такие проблемы. Особенно если работа не терпит отлагательств.
Содержание
- От чего возникает «Ошибка исключительной блокировки информационной базы»
- Во время работы с базой есть активные сеансы пользователей
- У пользователя запущенна база, но пароль не введён
- Зависшие сеансы в 1С
- Зависшие фоновые процессы
От чего возникает «Ошибка исключительной блокировки информационной базы»
Данное сообщение может появиться во время обновления или выгрузки базы данных 1С. Сообщение говорит о том, что база данных программы заблокирована для дальнейшего использования. Значит, для того, чтобы эту проблему устранить, необходимо выяснить, на каком уровне заблокирована база и как её разблокировать. Возможные причины мы и рассмотрим ниже.
Во время работы с базой есть активные сеансы пользователей
Когда происходит выгрузка или обновление базы 1С, все пользователи должны выйти из своего аккаунта. Если же они не вышли, то появится такая ошибка. В некоторых случаях может быть указанно, из-за каких именно пользователей появилась ошибка.
Список пользователей, которые сейчас не вышли из 1С, можно увидеть в разделе «Администрирование», в подразделе «Активные пользователи». Либо в самом сообщении об ошибке.
Чтобы решить проблему в таком случае, нужно просто попросить выйти этих пользователей из 1С, сохранив изменения. А затем, после завершения процедуры с базой данных им можно будет снова войти.
Подробнее: На сервере 1С: Предприятия произошла неисправимая ошибка. Приложение будет закрыто.
У пользователя запущенна база, но пароль не введён
Сложность этой проблемы в том, что в ошибке исключительной блокировки информационной базы не будет указанно имя того пользователя, по вине которого это произошло. А самого этого пользователя не будет видно в списке активных.
Чтобы решить данную проблему, можно самостоятельно поискать этих пользователей, и попросить их ввести пароль, чтобы войти, а затем выйти, закрыв базу.
Но если найти пользователя не удаётся, то можно попытаться отыскать его процесс в диспетчере задач и завершить его. Для запуска диспетчера задач, нажмите правой кнопкой мышки на панель задач, а затем «Диспетчер задач» (или можно просто нажать сочетание клавиш Ctrl + Alt + Del).
Найдите процессы с названиями 1Cv8.exe и/или 1Cv8c.exe, и выделите мышкой.
Затем внизу диспетчера нажмите «Снять задачу».
Будьте осторожны, при таком завершении работы пользователя, данные внесённые им во время работы в программу 1С, которые он не успел сохранить, окажутся безвозвратно потеряны.
Ошибка исключительной блокировки информационной базы такого характера возникает в файловых базах данных.
Зависшие сеансы в 1С
Если вы убедились в том, что все пользователи вышли из своих учётных записей, а также нет пользователей, которые запустили базу, но не ввели пароль, то проблема может быть в зависших сеансах. Определить, какой конкретно пользователь завис, будет также затруднительно, так как в активных пользователях он может не отображаться.
Поэтому решить данную проблему можно также с помощью диспетчера задач — найти процесс пользователя и принудительно его завершить, как было описано выше. Опасаться за не сохранения внесённых данных здесь уже не нужно, так как они всё равно не сохранятся, раз сеанс завис.
Вам может быть это интересно: Соединение с сервером баз данных разорвано администратором в 1С.
Зависшие фоновые процессы
Зависать могут не только сеансы пользователей, но и процессы, работающие в фоне. Особенностью данной причины является то, что название зависшего процесса также не отображается в сообщении об ошибке, поэтому определить его бывает затруднительно.
Список фоновых заданий можно увидеть в разделе «Процессы» в консоли администрирования 1С. И если попытаться удалить их, то пользователь может быть неприятно удивлён тем, что они появляются снова и опять мешают выгрузке базы. Здесь можно порекомендовать лишь попробовать закрыть такие задачи несколько раз. А если это не помогает, то в свойствах задачи включить опцию «Блокировка регламентных заданий включена», а затем снова попытаться закрыть.
Для того, чтобы успешно решить проблему ошибки исключительной блокировки информационной базы в 1С, следует попытаться установить её причину. Иногда её видно в самом сообщении об ошибке, когда, например, оно отображает имя активных пользователей, мешающих выгрузке или обновлению базы. А в других случаях приходится искать проблему самостоятельно. Если вам не удаётся устранить эту ошибку своими силами, то следует обратиться в службу поддержки сервиса, который занимается обслуживанием 1С на вашем предприятии.
Содержание
1. Ошибка 1С: “Конфликт блокировок при выполнении транзакции”. В чем причина?
2. Ошибки в 1С из-за блокировок
2.1 Пример необходимой блокировки в 1С
2.2 Пример избыточной блокировки в 1С
2.3 Как избавиться от избыточных блокировок в 1С
Ошибка 1С: “Конфликт блокировок при выполнении транзакции”. В чем причина?
Этот вопрос возник у нас на проекте по внедрению ЗУП2.5 с численностью 20000 и средним количеством одновременных пользовательских сессий 200.
На этапе опытной эксплуатации при расчете зарплаты пользователи начали интенсивно работать с документами «Начисление зарплаты сотрудникам организаций». Объем документов был порядка 2500 строк. У пользователей начали появляться сообщения «Конфликт блокировок при выполнении транзакции», и расчет приходилось запускать заново.
Стали разбираться. Оказалось, мы столкнулись с эффектом «Избыточной блокировки». Обычно этот эффект появляется при параллельном проведении документов, во время него самым первым документом блокируется большой объем записей регистров на все время проведения документа. Эта блокировка задерживает проведение остальных документов, мешает параллельной работе пользователей и замедляет рабочий процесс. Вообще блокировка данных при проведении документов вещь полезная, она сохраняет целостность данных и гарантирует правильность выполнения расчетных алгоритмов. Но бывает так, что либо объем заблокированных данных чрезмерен, либо время блокировки слишком велико. В результате мы имеем многопользовательскую систему, которая по сути является однопользовательской: вместо параллельного проведения документов — последовательное.
Ошибки в 1С из-за блокировок
Пример необходимой блокировки в 1С
Представим такую ситуацию – есть два документа «Начисление зарплаты сотрудникам организаций», в которых указан одинаковый налоговый период, а на закладке НДФЛ указаны одинаковые сотрудники. Рассмотрим случай, когда блокировка вообще отсутствует. Если последовательно запускать расчет этих документов, то в первом сумма НДФЛ посчитается правильно, а во втором будет равна нулю, т.к. рассчитанный и фактически начисленный НДФЛ на момент проведения второго документа будут совпадать.
Но если запустить эти документы параллельно, то они одновременно начислят НДФЛ, не подозревая о существовании друг друга, и в результате налог удвоится. Если блокировка настроена верно, то первый документ, запущенный на долю секунды раньше второго, успеет первым прочитать и заблокировать данные о фактически исчисленном налоге в регистре «НДФЛ расчеты с бюджетом» по сотруднику Пушкину А.С. Из этого запроса будет видно, что фактический налог за январь пока не начислялся и значит надо выполнить движение по регистру. Блокировка будет отпущена только после завершения записи в регистр. Второй документ, дойдя до запроса чтения фактически начисленного налога будет поставлен системой на ожидание до тех пор, пока первый документ не закончит транзакцию проведения, после чего он прочитает в запросе, что налог уже начислен и движение по регистру выполнять не надо. Это необходимая блокировка.
Конечно, этот пример притянут за уши для простоты объяснения. На самом деле логика ЗУП 2.5 такова, что для задвоения НДФЛ пользователям не нужно прикладывать особых усилий. НДФЛ рассчитывается до проведения документа, а при проведении содержимое табличной части просто заносится в регистры без всякой проверки. Пользователям между расчетом и проведением предоставляется возможность посмотреть будущий результат и при необходимости поправить руками. Конечно это большой плюс в пользу гибкости ЗУПа, но предъявляет высокие требования к профессиональному уровню расчетчиков. Поэтому вопрос предотвращения задвоения НДФЛ решается организационным путем или с помощью дополнительных проверочных отчетов. Конечно, в ЗУП2.5 есть регистры, которые рассчитываются и записываются одновременно при проведении документа, например «НДФЛ к зачету», но этот пример пришлось бы дольше объяснять ;).
Пример избыточной блокировки в 1С
А теперь представим другую ситуацию. При проведении документа выполняется запрос, который должен отобрать документы, в которых присутствует сотрудник из этого документа. Но запрос написан так, что сервер SQL вынужден находить нужные документы методом перебора. Для технических специалистов это означает, что вместо CLUSTERED INDEX SCAN выполняется TABLE SCAN, т.е. вместо сканирования таблицы индексов происходит сканирование самой таблицы. Причем в процессе перебора блокируются все записи, к которым прикоснулся запрос, даже те, в которых не присутствуют искомые сотрудники. И эта блокировка будет действовать до конца завершения проведения документа, что будет препятствовать параллельному проведению документов с другими сотрудниками. Это избыточная блокировка.
Как избавиться от избыточных блокировок в 1С
Лечение избыточных блокировок может идти двумя путями. Первый — это оптимизация запросов, выполняемых внутри транзакций и добавление необходимых табличных индексов в конфигураторе. Второй — это перевод выполнения SQL-запросов на более низкий уровень изоляции, когда при выполнении запросов записи в таблицах блокируются только на момент выполнения самого запроса, либо не блокируются вовсе. А необходимые блокировки устанавливаются средствами объекта «БлокировкаДанных» и выполняются на стороне сервера 1С.
Теперь немного теории про уровни изоляции на SQL сервере:
1. В автоматическом режиме в транзакциях используется уровень изоляции SERIALIZABLE. Этот уровень накладывает блокировки типа X (запрещает чтение и запись) до конца транзакции на все данные, которых коснулись запросы или произошла запись данных.
2. В управляемом режиме в транзакциях используется уровень изоляции ReadCommitted. Этот уровень на записанные данные также устанавливает блокировки типа X до конца транзакции. Но при выполнении запросов на данные накладывает блокировки типа S (запрещает запись и проверяет нет ли в этот момент параллельных записей), при завершении запроса блокировки снимаются не дожидаясь завершения транзакции.
3. Если база данных переведена в режим ReadCommitted SNAPSHOT, то в управляемом режиме при чтении данных не накладывается блокировка типа S, есть только блокировка типа X при записи.
Тоже самое чуть более подробно в таблице:
Обычно лечение начинают с понижения уровня изоляции, т.к. это не особо трудозатратно и дает быстрый результат. Достаточно перевести конфигурацию из «Автоматического» режима управления блокировкой данных в «Управляемый», и транзакции начнут выполняться на уровне изоляции типа ReadCommitted, вместо SERIALIZABLE или Repeatable Read.
Чтобы переключить базу данных в режим READ COMMITTED SNAPSHOT (RCSI) необходимо в «SQL Server Management Studio» в свойствах базы данных установить параметр «Is Read Committed Snapshot On» в значение «True»:
В некоторых источниках предлагают установить параметр «Allow Snapshot Isolation» в значение «True», но в этом нет необходимости, т.к. это приведет к включению другого режима изоляции SNAPSHOT, который не поддерживается платформой 1С (На момент написания статьи релиз платформы 8.3.9).
Режим управления блокировкой данных задается для неявных транзакций, которые выполняются при записи или при проведении документов, т.е. внутри предопределенных процедур типа ПриЗаписи() или ОбработкаПроведения(). Но большинство «тяжелых» вычислений в типовой конфигурации ЗУП2.5 происходит при выполнении команды «Рассчитать». При этом в модуле объекта запускается процедура РассчитатьВсе(), внутри которой неоднократно повторяется конструкция НачатьТранзакцию() …ЗафиксироватьТранзакцию(). Это явно указанные транзакции, внутри которых происходит запись и очистка регистров и выполняются запросы. Нам необходимо убедиться, что при переключении конфигурации в управляемый режим в процедуре «РассчитатьВсе()» транзакции также начинают выполняться на уровне ReadCommitted.
Для этого проведем небольшой эксперимент:
• Запустим SQL Server Profiler.
• Запустим «NEW TRACE».
• Выполним подключение к серверу SQL.
• В окне «Trace Properties» на закладке «General» выберем «Use the template» = «Blank», а на закладке «Events Selections» раскроем группу «Stored Procedures» и выберем «RPC:Complited». По кнопке «Column Filters» укажем имя базы и длительность выполнения запросов более 1.
• Кнопку RUN пока нажимать не будем, т.к. нам надо сначала запустить базу данных в режиме отладки и остановить выполнение расчета документа «Начисление зарплаты сотрудникам организаций» перед выполнением самого массивного запроса. Например, это будет команда
«Результат = Запрос.ВыполнитьПакет();» в функции «ПолучитьДанныеНДФЛПоРегистратору» в общем модуле «ПроведениеРасчетов». Здесь происходит выполнение основного запроса для расчета НДФЛ. Поставим на ней точку останова отладчика и запустим расчет в документе.
· После того как отладчик остановится, нажмем кнопку RUN в Профайлере.
· Теперь сделаем один шаг в отладчике кнопкой F11. Когда запрос будет выполнен и отладчик перейдет на следующий шаг, остановим чтение Профайлера кнопкой «Pause Selected Trace».
· Теперь найдем самый длительный запрос по колонке Duration и внимательно изучим текст запроса. Если при обращении к реальной (а не временной) таблице после слова WITH стоит SERIALIZABLE, то мы имеем дело с автоматическим режимом блокировки. Если ничего не стоит – то с управляемым.
Если в хинте запроса (Hint – это параметр после слова WITH, позволяющий влиять на план выполнения запроса) не указан уровень изоляции, то выполняется уровень изоляции, установленный по умолчанию для текущей SQL-сессии. Определить уровень изоляции, действующий по умолчанию для текущих сессий можно в «SQL Server Management Studio» с помощью команды
SEL ECT CASE transaction_isolation_level
WHEN 0 THEN ‘Unspecified’
WHEN 1 THEN ‘ReadUncommitted’
WHEN 2 THEN ‘ReadCommitted’
WHEN 3 THEN ‘Repeatable’
WHEN 4 THEN ‘SERIALIZABLE’
WHEN 5 THEN ‘SNAPSHOT’ END AS TRANSACTION_ISOLATION_LEVEL
FR OM sys.dm_exec_sessions
В управляемом режиме для всех сессий будет указан режим ReadCommitted.
Таким образом мы получили экспериментальное подтверждение того, что после перевода в управляемый режим всей конфигурации, в этом режиме начинают работать не только процедуры записи и проведения, но и процедуры расчета документов ЗУП. А это значит, что количество сообщений о конфликте блокировок будет существенно снижено, а параллельность работы с базой данных увеличится.
После того, как включили управляемый режим блокировки мы должны убедиться, что избавившись от избыточных блокировок, мы не ушли в другую крайность и не потеряли необходимые блокировки, которые защищают систему от нарушения целостности данных при активной параллельной работе пользователей.
Настройка управляемых блокировок – это тема для отдельной статьи. Вкратце скажу, что программно управляемые блокировки устанавливаются с помощью объекта «БлокировкаДанных». Сами управляемые блокировки работают уже не на уровне SQL сервера, как в случае с автоматическими блокировками, а на уровне сервера 1С. Для определения необходимых и достаточных управляемых блокировок надо понимать логику программы одновременно на уровне бизнес-процессов и на уровне архитектуры таблиц СУБД.
Но на мой взгляд, для таких конфигураций, как ЗУП2.5 вообще нет смысла использовать какие-либо блокировки, лучше использовать проверочные отчеты для выявления нарушения целостности данных — на практике это самый быстрый способ расчета зарплаты. Особенно на крупных предприятиях, где точно есть сотрудники с внутренним совмещением в обособленных подразделениях, а за каждым ОП закреплен отдельный расчетчик, что и является причиной задвоения НДФЛ. Какой бы не был вышколенный персонал, сама идеология конфигурации допускает возможность задвоения НДФЛ. Поэтому лучше не мешать пользователям работать параллельно во время массированных месячных расчетов, а по завершении точечно и быстро исправить небольшой процент ошибок, чем заставлять их сидеть и нервничать в очереди из-за страха допустить хотя бы одну ошибку. В этом проекте мы использовали самописный отчет «Проверка НДФЛ», который отображал сотрудников с некорректным НДФЛ.
Так же на этом проекте мы столкнулись с эффектом «Эскалация блокировок», когда SQL сервер сам принимает решение, что надо укрупнить область наложения блокировок вплоть до блокировки целиком всей таблицы. В результате работа пользователей останавливается, и все ждут завершения проведения одного документа – виновника эскалации, либо когда по таймауту снимутся взаимные блокировки, либо произойдет перезагрузка сервера. В каких случаях возникает эскалация и как с этим бороться тоже тема для отдельной статьи.
Валерий Федоров
Руководитель проектов ООО “Кодерлайн”