Как устранить конфликт блокировок при обмене данными РИБ в 1С на PostgreSQL и Linux?

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

При настройке автоматического обмена данными в распределенной информационной базе (РИБ) по расписанию администраторы и разработчики нередко сталкиваются с ошибкой: «Ошибка при вызове метода контекста (ЗаписатьИзменения): Конфликт блокировок при выполнении транзакции: Превышено максимальное время ожидания предоставления блокировки» (или ее англоязычным аналогом: Lock conflict during the transaction: Maximum idle time for lock access has been exceeded due to the wait for the session). При этом ручной обмен может успешно отрабатывать, а регламентные задания приводят к блокировкам в СУБД, которые не снимаются даже перезапуском сеансов пользователей.

Разберем детально причины возникновения этой ошибки в связке 1С:Предприятие + PostgreSQL + Linux и пошагово рассмотрим способы устранения проблемы.

Причины возникновения блокировок при сценариях обмена

Проанализируем механику работы обмена данными в 1С. Метод ЗаписатьИзменения() открывает транзакцию и считывает накопленные записи из служебных таблиц регистрации изменений (_ChangeRec). В процессе работы могут возникать следующие коллизии:

  1. Ошибки платформы 1С при работе с СУБД: В некоторых релизах платформы (в частности, в ветке 8.3.9) присутствовали ошибки менеджера блокировок и механизмов управления пулом соединений к PostgreSQL на Linux, из-за которых сессии СУБД зависали и удерживали транзакцию открытой.
  2. Зависшие транзакции в статусе idle in transaction: Если фоновое задание прерывается аварийно или соединение между сервером 1С (rphost) и PostgreSQL разрывается некорректно, процесс в PostgreSQL остается в состоянии ожидания с наложенными эксклюзивными блокировками на таблицы изменений.
  3. Наложение расписаний регламентных заданий: Если время формирования пакета обмена превышает интервал между запусками фонового задания, стартует второй процесс обмена, пытающийся обработать тот же узел плана обмена, что вызывает взаимоблокировку (Deadlock) или таймаут.
  4. Большой объем изменений: Попытка выгрузить огромный массив данных в одной транзакции блокирует таблицы регистрации на длительное время, не давая параллельным процессам завершить работу.

Шаг 1. Проверка и смена релиза платформы 1С

Если вы используете релизы платформы 8.3.9 (например, 8.3.9.2170 или 8.3.9.2033) в связке с PostgreSQL на Linux, основной причиной блокировок является баг платформы в обработке транзакций СУБД.

Для устранения проблемы выполним обновление платформы на более стабильные старшие релизы (например, 8.3.10, 8.3.12 и новее) либо произведем откат на стабильную ветку 8.3.8 (например, 8.3.8.1652). На практике смена проблемного релиза 8.3.9 полностью снимает ложные зависания при вызове метода ЗаписатьИзменения().

Шаг 2. Диагностика и снятие зависших процессов в PostgreSQL

Выясним, какие процессы блокируют таблицы на стороне базы данных. Подключимся к СУБД через консоль psql или pgAdmin и выполним запрос для поиска сессий, находящихся в транзакции без активности:


SELECT pid, usename, client_addr, state, query, age(clock_timestamp(), query_start) 
FROM pg_stat_activity 
WHERE state = 'idle in transaction';

Если в выводе запроса присутствуют длительно висящие процессы, снимем блокирующий процесс по его идентификатору (PID):

SELECT pg_terminate_backend(pid);

Чтобы СУБД автоматически сбрасывала брошенные транзакции и не копила взаимные блокировки, настроим конфигурационный файл postgresql.conf:

  1. Параметр idle_in_transaction_session_timeout = 600000 — устанавливает автоматическое завершение сессий, зависших в транзакции более чем на 10 минут.
  2. Параметр lock_timeout = 60000 — ограничивает максимальное время ожидания получения блокировки.
  3. Параметр max_locks_per_transaction = 256 — увеличивает лимит табличных блокировок для сложных операций РИБ.

После изменения параметров выполним перезагрузку конфигурации PostgreSQL командой SELECT pg_reload_conf(); или перезапустим службу СУБД.

Шаг 3. Настройка технологического журнала 1С для анализа блокировок

Если блокировки продолжают возникать, настроим технологический журнал платформы для детального выявления виновника конфликта. Разместим в каталоге настроек сервера 1С файл logcfg.xml со следующим содержимым:


<config xmlns="http://v8.1c.ru/v8/tech-log">
    <log location="/var/log/1c/logs" history="24">
        <event>
            <eq property="name" value="TLOCK"/>
        </event>
        <event>
            <eq property="name" value="TTIMEOUT"/>
        </event>
        <event>
            <eq property="name" value="TDEADLOCK"/>
        </event>
        <property name="all"/>
    </log>
</config>

События TLOCK, TTIMEOUT и TDEADLOCK покажут точный текст транзакции, контекст выполнения в конфигурации 1С и номера сеансов, которые удерживают ресурс и не дают выполниться записи данных.

Шаг 4. Корректировка сценариев обмена и регламентных заданий

Для предотвращения конфликтов при работе по расписанию настроим параметры запуска регламентных задач в конфигурации:

  1. Интервал запуска: Увеличим интервал между сеансами фонового обмена. Если выгрузка занимает 3 минуты, запуск обмена каждые 60 секунд гарантированно приведет к наложению сеансов.
  2. Очистка избыточной регистрации: Если узел накопил слишком много записей, выполним порционную выгрузку или снимем лишнюю регистрацию изменений с помощью метода ПланыОбмена.УдалитьРегистрациюИзменений().
  3. Разделение регламентных процедур: Разнесем по времени сценарии синхронизации РИБ и тяжелые регламентные операции (пересчет итогов регистров, обновление индекса полнотекстового поиска).
← На главную