Как добавить субконто Партии на счет 41 в 1С:Бухгалтерия 3.0 при большом объеме данных и ошибках блокировки

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При работе с крупными информационными базами «1С:Бухгалтерия 3.0», где количество проводок по счету 41.01 исчисляется миллионами, стандартная операция включения партионного учета превращается в сложную техническую задачу. Попытка добавить субконто Партии через настройки параметров учета или напрямую в плане счетов часто приводит к ошибке "lock request time out period exceeded" (превышено время ожидания блокировки). Это происходит потому, что система пытается в рамках одной транзакции изменить структуру огромной таблицы регистра бухгалтерии и пересчитать итоги.

В этой статье мы подробно разберем, почему возникает эта проблема, и проанализируем пошаговые стратегии ее решения, используя инструменты платформы 1С и MS SQL Server.

Почему возникает конфликт блокировок при добавлении субконто

Разберем ситуацию изнутри. Когда мы добавляем новое субконто на счет, платформа инициирует процесс реструктуризации таблиц базы данных. Основная нагрузка ложится на таблицу движений регистра бухгалтерии (обычно это _AccRg) и связанные с ней таблицы итогов. Если в таблице миллионы записей, SQL Server не может бесконечно блокировать отдельные строки и применяет механизм Lock Escalation (эскалация блокировок), блокируя таблицу целиком.

Даже если в базе «никого нет», конфликт могут вызвать:

  1. Фоновые и регламентные задания, которые не были отключены в консоли кластера.
  2. Внутренние системные процессы 1С, пытающиеся обновить кэш или статистику.
  3. Слишком короткий таймаут ожидания блокировки в настройках 1С, из-за чего транзакция прерывается раньше, чем SQL Server успевает обработать данные.

Шаг 1. Подготовка инфраструктуры и настройка кластера 1С

Прежде чем приступать к изменениям, проанализируем настройки кластера серверов 1С. По умолчанию время ожидания блокировки составляет 20 секунд. Для реструктуризации миллионов строк этого катастрофически мало.

Выполним следующие действия:

  1. Зайдем в консоль администрирования кластера серверов 1С.
  2. Откроем свойства нашей информационной базы.
  3. Найдем параметр «Таймаут времени ожидания блокировки» и временно увеличим его до 5000 или более секунд.
  4. Убедимся, что установлена галочка «Блокировка регламентных заданий включена». Это гарантирует, что никакое фоновое задание не «проснется» в середине процесса.

Шаг 2. Оптимизация SQL Server для массовых операций

На стороне SQL Server также требуется провести подготовку. Основная проблема — рост лога транзакций и параллелизм, который может привести к взаимоблокировкам (deadlocks) процесса самого с собой.

Рассмотрим рекомендации по настройке SQL:

  1. Модель восстановления: Переведем базу данных в модель Simple. Это предотвратит бесконтрольный рост файла .LDF во время добавления субконто.
  2. Параметр MAXDOP: Установим Max Degree of Parallelism = 1. Это заставит SQL выполнять операцию в одном потоке, исключая ожидания типа CXPACKET.
  3. Эскалация блокировок: Для конкретной таблицы регистра бухгалтерии можно попробовать отключить эскалацию, чтобы SQL не пытался захватить всю таблицу сразу.

Пример команды для SQL Server Management Studio:


-- Перевод в Simple (замените MyBase на имя вашей базы)
ALTER DATABASE [MyBase] SET RECOVERY SIMPLE;

-- Отключение эскалации блокировок для таблицы регистра бухгалтерии
-- Имя таблицы нужно предварительно уточнить (например, через ПолучитьСтруктуруХраненияБазыДанных)
ALTER TABLE [_AccRg12345] SET (LOCK_ESCALATION = DISABLE);

Шаг 3. Управление итогами регистра бухгалтерии

Значительная часть времени при добавлении субконто тратится на пересчет итогов. Мы можем обмануть систему, временно отключив их. Выясним, как это сделать программно.

Создадим небольшую внешнюю обработку и выполним следующий код:


// Отключаем использование итогов, чтобы ускорить реструктуризацию
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Ложь);
// Также можно отключить текущие итоги
РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеТекущихИтогов(Ложь);

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

Шаг 4. Использование механизма «Тестирование и исправление»

Иногда ручное внесение изменений в план счетов через интерфейс "1С:Предприятие" вызывает более сложные цепочки блокировок, чем работа в конфигураторе. Проанализируем следующий алгоритм:

  1. Внесем изменения в План счетов в Конфигураторе (добавим субконто Партии).
  2. Применим изменения (F7). Если на этом этапе возникает таймаут, значит, база слишком велика для стандартной реструктуризации.
  3. Если обновление прошло успешно в метаданных, но данные не обновились, запустим «Тестирование и исправление» с включенными опциями «Проверка логической целостности» и «Пересчет итогов».

Шаг 5. Программное заполнение субконто порциями

Если стандартные механизмы все равно выдают ошибку блокировки, применим «хитрый» метод: добавим субконто без автоматического заполнения, а затем заполним его данными вручную, используя технологические окна.

Рассмотрим по шагам:

  1. Добавим субконто в План счетов, но не будем включать его в обязательное заполнение.
  2. Напишем обработку, которая выбирает проводки по 41 счету и заполняет пустое субконто Партии (например, документом оприходования или специально созданной «партией по умолчанию») порциями по 10 000 – 50 000 записей.

Пример кода для порционной обработки данных:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 50000
    |	Хозрасчетный.Регистратор,
    |	Хозрасчетный.НомерСтроки
    |ИЗ
    |	РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
    |ГДЕ
    |	Хозрасчетный.СчетДт = &Счет41
    |	И Хозрасчетный.СубконтоДт1 = ЗНАЧЕНИЕ(Справочник.Партии.ПустаяСсылка)";

Запрос.УстановитьПараметр("Счет41", ПланыСчетов.Хозрасчетный.Товары);

Пока Истина Цикл
    Результат = Запрос.Выполнить().Выгрузить();
    Если Результат.Количество() = 0 Тогда Прервать; КонецЕсли;
    
    НачатьТранзакцию();
    Для Каждого Строка Из Результат Цикл
        // Здесь логика замены/установки субконто
        // Используем НаборЗаписей с фильтром по регистратору
    КонецЦикла;
    ЗафиксироватьТранзакцию();
КонецЦикла;

Рекомендации по завершению операции

После успешного добавления субконто и завершения всех манипуляций, не забудьте вернуть систему в рабочее состояние:

Таким образом, комбинируя настройку таймаутов кластера, оптимизацию SQL-сервера и программное управление итогами, мы можем успешно преодолеть конфликт блокировок даже на самых нагруженных базах «1С:Бухгалтерии 3.0».

← На главную