PostgreSQL 55P03 (1С): Выполнение оператора отменено из-за тайм-аута блокировки
Механизмы блокировок СУБД и транзакции 1С
Ошибка PostgreSQL 55P03 (lock_not_available) при работе с 1С транслируется пользователю как «Конфликт блокировок при выполнении транзакции» или «Выполнение оператора отменено из-за тайм-аута блокировки». Это происходит, когда один процесс (сеанс 1С) захватил эксклюзивную блокировку на строку или таблицу в БД (например, при проведении тяжелого документа), а другой процесс пытается прочитать или изменить эти же данные. Если первый процесс не отпускает блокировку дольше, чем задано в параметре lock_timeout (в 1С по умолчанию управляется таймаутом ожидания блокировки в 20 секунд), второй процесс аварийно завершается сервером PostgreSQL. Бизнес-риски: массовые отказы в проведении документов при одновременной работе пользователей (Concurrence issues).
Типовые причины конфликтов блокировок в 1С
| Операция в 1С | Режим блокировок (СУБД) | Почему возникает таймаут (55P03) |
|---|---|---|
| Массовое перепроведение документов | RowExclusiveLock (на таблицы регистров) | Длинная транзакция не отдает строки. Другие документы ждут в очереди. |
| Реструктуризация БД (Обновление) | AccessExclusiveLock (на всю таблицу) | Фоновое задание или пользователь пытается писать в таблицу, структура которой меняется. |
| Неоптимальные запросы без индексов | ShareLock / Эскалация блокировок | СУБД переходит от блокировки строк (Row) к блокировке целых страниц/таблиц из-за Seq Scan (полного сканирования). |
Алгоритм диагностики и устранения блокировок 55P03
Сценарий 1: Выявление виновника (Тяжелой транзакции) в PostgreSQL
Если блокировки происходят прямо сейчас, необходимо найти PID процесса, который удерживает ресурс, используя системные представления PostgreSQL.
Запрос для поиска блокирующих и ожидающих транзакций (в psql/pgAdmin)
SELECT
blocked_locks.pid AS blocked_pid,
blocked_activity.usename AS blocked_user,
blocking_locks.pid AS blocking_pid,
blocking_activity.usename AS blocking_user,
blocked_activity.query AS blocked_statement,
blocking_activity.query AS current_statement_in_blocking_process
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;Сценарий 2: Перевод 1С на Управляемые блокировки
Классическая ошибка — использование режима совместимости с «Автоматическими блокировками» (уровень изоляции Serializable в СУБД). Управляемые блокировки (Managed Locks) перекладывают контроль с PostgreSQL на сервер 1С (Менеджер блокировок), что резко снижает вероятность 55P03.
- В свойствах конфигурации установите Режим управления блокировками данных =
Управляемый. - В коде проведения используйте объект
БлокировкаДанныхдля наложения точечных эксклюзивных блокировок на конкретные измерения регистров (например, Товар + Склад).
Типовые ошибки администраторов
- Увеличение lock_timeout в postgresql.conf: Увеличение таймаута не решает проблему, а лишь маскирует её. Вместо ошибки пользователи будут видеть просто зависший интерфейс на 2-3 минуты. Проблему нужно решать оптимизацией кода (уменьшением времени транзакции).
Ручной поиск дедлоков (взаимоблокировок) в логах СУБД — адский труд. Администраторы баз данных ITSTM настроят сбор Технологического журнала 1С (события TTIMEOUT, TLOCK), проведут профилирование кода 1С и перепишут узкие места на Управляемые блокировки, обеспечив параллельную работу сотен пользователей.
Частые вопросы (FAQ)
Почему ошибка 55P03 происходит при динамическом обновлении?
При динамическом обновлении сервер 1С пытается записать новые структуры метаданных. Если в этот момент пользователи активно работают с таблицами, возникает конкуренция за AccessExclusiveLock. Именно поэтому 1С настоятельно не рекомендует обновлять базы динамически.
Влияет ли параметр 'Время ожидания блокировки данных' в настройках базы 1С?
Да. По умолчанию в 1С он равен 20 секундам. Именно он передается в СУБД PostgreSQL как команда 'SET lock_timeout = 20000' для каждой сессии.
Как убить зависшую транзакцию в PostgreSQL?
Используйте функцию pg_cancel_backend(PID) для мягкой отмены запроса, или pg_terminate_backend(PID) для жесткого разрыва сетевого соединения с процессом rphost. PID блокирующего процесса можно узнать через запрос к pg_stat_activity.
Deadlock (40P01) и Timeout (55P03) — это одно и то же?
Нет. Таймаут (55P03) — это когда процесс А долго держит ресурс, а процесс Б просто не дождался очереди. Дедлок (40P01 / Взаимоблокировка) — это перекрестная блокировка: процесс А ждет ресурс процесса Б, а Б ждет ресурс А. СУБД мгновенно убивает один из них, не дожидаясь таймаута.