Взаимоблокировки при записи в регистры 1С на PostgreSQL: что показал стенд на 20 потоках

22.10.26

База данных - HighLoad оптимизация

Проверила на стенде совет «сортируйте строки перед записью»: 1С 8.3.27 на PostgreSQL, учебная «Нано-УТ», 20 потоков и по 2000 документов на каждый способ записи движений. Взаимоблокировки дают построчный захват (99 % ошибок) и повышение разделяемой блокировки до исключительной (95 %, сортировка не помогает); одна блокировка на весь набор работает без сортировки. Плюс механика PostgreSQL, дерево ожиданий через pg_blocking_pids, TDEADLOCK в журнале и единицы порога TLOCK в logcfg.xml. В архиве стенд, выгрузка конфигурации и журналы прогона.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Стенд: взаимоблокировки при записи в регистр 1С на PostgreSQL (21.10.2026)
.zip 637,10Kb
0 4 200 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.
Администрирование 1С
О чём это (в четырёх тезисах)
1.В управляемом режиме на стенде все 3876 взаимоблокировок из 12 000 документов нашёл менеджер блокировок 1С (TDEADLOCK, «Неустранимый конфликт блокировок»); PostgreSQL не выдал ни одного deadlock detected.
2.Построчная блокировка в порядке документа дала 99,1 % ошибок, разделяемая с повышением до исключительной - 94,7 %, сортировка строк от второго случая не спасает.
3.Набор.Записать() и одна БлокировкаДанных на весь набор блокируют все строки сразу: 0 ошибок при любом порядке строк.
4.Порог TLOCK в logcfg.xml задаётся в сотнях микросекунд: 30000 - это 3 секунды, а 3000000 - 300 секунд и не срабатывает никогда.
Протокол проверки
Что проверялосьШесть способов записи движений регистра остатков, штатное проведение «Нано-УТ», механика блокировок PostgreSQL, технологический журнал.
Где и когда21.10.2026, Windows 11 Pro, i5-2400; 1С 8.3.27.2130 x86, серверная база на Postgres Pro 1C 17.10; PostgreSQL 16.15 для опыта без 1С.
Как20 фоновых заданий × 100 документов × 5 строк в случайном порядке на каждый способ; psql-сеансы в обратном порядке; тонкий клиент; ТЖ с тремя порогами.
РезультатОшибок: 0, 1982, 0, 0, 0 и 1894 из 2000 по способам; остатки сошлись; проведение «Нано-УТ» - 0 взаимоблокировок и 14 таймаутов из 100.
ГраницыАвтоматический режим, PostgreSQL 16 для 1С, Linux, типовые конфигурации и регистры с разделением итогов не проверялись.
Суть статьи

Где на самом деле возникают взаимоблокировки при параллельной записи в регистр 1С на PostgreSQL и что из привычных советов на них влияет. Способы записи движений проверены на 20 потоках, механика СУБД - прямыми сеансами psql, журнал - на трёх порогах.

Ключевые идеи
  • Взаимоблокировку даёт захват блокировок по частям: по строке в цикле или разделяемая, потом исключительная.
  • При Набор.Записать() платформа сама ставит исключительную блокировку на все строки набора одним вызовом.
  • Сортировка нужна только построчному захвату и превращает ошибки в очередь: медиана 958 → 2575 мс.
  • В PostgreSQL ждут ShareLock на transactionid; RowExclusiveLock в цикле не участвует, корень показывает pg_blocking_pids().
  • В фильтре logcfg.xml duration в сотнях микросекунд, в записях журнала - в микросекундах.
Главная мысль

Брать управляемую блокировку на все строки документа одним вызовом и сразу в нужном режиме; сортировка строк от взаимоблокировок при таком захвате не нужна.

Для кого: разработчики и администраторы 1С, у которых при параллельном проведении документов появляется «Конфликт блокировок при выполнении транзакции».

Оглавление:
  1. Стенд
  2. Где лежат движения регистра в PostgreSQL
  3. Две разные взаимоблокировки
  4. Взаимоблокировка строк в PostgreSQL 16
  5. Кто кого держит: дерево ожиданий
  6. Что делает платформа при записи набора
  7. Способы записи движений: замер
  8. Что видит пользователь
  9. Технологический журнал: что ловить и в каких единицах
  10. Как записывать движения
  11. Предельный случай: одна блокировка на всё проведение
  12. Практические правила
  13. Что не проверялось
  14. Итог
  15. Источники
  16. Файл к статье

Когда два оператора одновременно проводят документы с одними и теми же товарами, один из них иногда получает «Конфликт блокировок при выполнении транзакции». Обычный совет на этот случай - сортировать строки перед записью, чтобы все транзакции брали ресурсы в одном порядке. Я проверила этот совет на стенде: 1С:Предприятие 8.3.27 на PostgreSQL, учебная конфигурация «Нано-УТ», 20 параллельных сеансов и по 2000 документов на каждый способ записи движений. Сортировка помогла там, где блокировки берутся по строке в цикле, и не повлияла ни на что остальное. Ниже - где именно возникает взаимоблокировка, что при записи набора делает сама платформа, как найти виновника в PostgreSQL и в технологическом журнале и какие настройки журнала на самом деле ничего не ловят.

Всё запускалось на одном компьютере 21 октября 2026 года; журналы, снимки и стенд лежат в архиве к статье.

Стенд

Условие Значение
Платформа 1С:Предприятие 8.3.27.2130 (x86), отдельный экземпляр кластера (ragent на портах 1740/1741), серверная база
СУБД для базы 1С Postgres Pro 1C 17.10 в контейнере Docker. Сборки PostgreSQL 16 для 1С на стенде нет
СУБД для опыта без 1С PostgreSQL 16.15 (официальный образ postgres:16), deadlock_timeout = 1s, log_lock_waits = on
Конфигурация «Нано-УТ 2.0» - наша учебная торговая конфигурация: справочники «Номенклатура», «Склады», документ «ПродажаТовара», регистр остатков «ТоварыНаСкладах» (измерения Склад и Номенклатура, ресурсы Количество и Стоимость), управляемый режим блокировок. Для опыта добавлены общий модуль ДедлокСтенд и обработка СтендВзаимоблокировок
Нагрузка 20 фоновых заданий кластера (отдельные сеансы и соединения с СУБД), в каждом 100 документов по 5 строк; строки в документе в случайном порядке, как их набирает оператор; внутри транзакции пауза 20 мс - расчёт, пока блокировки удерживаются
Компьютер Intel Core i5-2400 3,1 ГГц (4 ядра, 2011 год), 7,9 ГБ ОЗУ, SSD Samsung 850 EVO (SATA), Windows 11 Pro 10.0.22631; Docker Desktop 29.8.0, ВМ на 4 ядра. Компьютер рабочий: во время замеров были открыты браузер и приложение Claude

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

Где лежат движения регистра в PostgreSQL

В базе стенда регистр «ТоварыНаСкладах» лежит в двух таблицах; номера в именах платформа выдаёт сама, у вас они будут свои:

Таблица Что в ней Колонки (по information_schema.columns)
_accumrg246 движения _period, _recordertref, _recorderrref, _lineno, _active, _recordkind, _fld247rref (склад), _fld248rref (номенклатура), _fld249 и _fld250 (количество и стоимость)
_accumrgt251 итоги по периодам _period, _fld247rref, _fld248rref, _fld249, _fld250

Ссылочное измерение в PostgreSQL - колонка _fldNNNrref типа bytea. Регистратором этого регистра бывают документы нескольких видов, поэтому рядом с _recorderrref есть _recordertref - номер типа регистратора. Настройки итогов хранятся в отдельных таблицах _accumrgoptNNN (_regid, _actualperiod, _usetotals, _usesplitter); итогов в них нет, а номер в имени с номером регистра не совпадает.

Эти же номера встречаются в технологическом журнале: пространство управляемых блокировок AccumRg246.DIMS - измерения регистра _accumrg246, поля Fld247 и Fld248 - склад и номенклатура.

Две разные взаимоблокировки

В базе 1С на PostgreSQL взаимоблокировку может обнаружить любая из двух сторон.

СУБД. Если две транзакции обновляют одни и те же строки в разном порядке, PostgreSQL через deadlock_timeout находит цикл и прерывает одну из них с ERROR: deadlock detected.

Менеджер управляемых блокировок 1С. В управляемом режиме платформа сначала ставит собственные блокировки на пространства данных (регистр, измерения, значения) и только потом обращается к СУБД. Если цикл образуется на этих блокировках, менеджер 1С находит его сам. Пользователь видит «Неустранимый конфликт блокировок», а технологический журнал пишет событие TDEADLOCK.

На стенде за 12 000 документов все 3876 взаимоблокировок были второго вида; deadlock detected от PostgreSQL не появился ни разу. Первый вид я воспроизвела отдельно, прямыми запросами к PostgreSQL 16, чтобы показать механику СУБД.

Взаимоблокировка строк в PostgreSQL 16

Опыт без 1С: таблица итогов из трёх строк, два сеанса psql. S1 обновляет «Товар А», потом «Товар Б». S2 обновляет «Товар Б», потом «Товар А». Третье окно в момент ожидания снимает pg_locks и pg_blocking_pids().

Рис. 1. Сеанс S2 замыкает цикл и через секунду получает ERROR: deadlock detected (PostgreSQL 16.15)
Рис. 2. pg_locks в момент ожидания: RowExclusiveLock выдана обоим сеансам, S1 ждёт ShareLock на транзакцию S2

Что видно на снимках:

  • RowExclusiveLock на таблицу totals выдана обоим сеансам одновременно (granted = t). Это блокировка уровня таблицы, которую берёт любой UPDATE, INSERT или DELETE. Сама с собой она не конфликтует, поэтому к взаимоблокировке отношения не имеет.
  • Ждёт сеанс другого: S1 запрашивает ShareLock на transactionid транзакции S2, то есть ждёт её завершения. Когда к одной строке выстраивается очередь, следующий в очереди ещё держит ExclusiveLock на tuple.
  • Текст ошибки СУБД называет обе стороны: «Process 280 waits for ShareLock on transaction 751; blocked by process 281. Process 281 waits for ShareLock on transaction 752; blocked by process 280».
  • Цикл находит сам ждущий процесс, отдельного фонового процесса для этого нет. В журнале сервера: «process 117 detected deadlock while waiting for ShareLock on transaction 745 after 1000.277 ms». В документации deadlock_timeout описан так же: столько сеанс ждёт, прежде чем проверить, не попал ли он в цикл; по умолчанию 1 секунда.
  • Когда оба сеанса берут строки в одном порядке, второй ждёт первого на первой же строке и после его фиксации проходит без ошибки.

Кто кого держит: дерево ожиданий

Для поиска корня очереди удобна функция pg_blocking_pids(pid): она возвращает сеансы, которые мешают данному получить блокировку, и сама учитывает очередь к строке. Запрос из архива строит по ней дерево: корень - сеанс, который держит блокировку и сам никого не ждёт.

SQL UTF-8 фрагмент
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WITH RECURSIVE w AS (
    SELECT DISTINCT a.pid, b.blocker
    FROM pg_stat_activity a, unnest(pg_blocking_pids(a.pid)) AS b(blocker)
), roots AS (
    SELECT DISTINCT blocker AS pid FROM w WHERE blocker NOT IN (SELECT pid FROM w)
), tree AS (
    SELECT r.pid, NULL::int AS blocker, 0 AS depth, ARRAY[r.pid] AS path FROM roots r
    UNION ALL
    SELECT w.pid, w.blocker, t.depth + 1, t.path || w.pid
    FROM w JOIN tree t ON w.blocker = t.pid
    WHERE NOT w.pid = ANY (t.path)
)
SELECT repeat('  ', t.depth) || t.pid::text AS pid_tree, t.blocker AS waits_for,
       a.application_name AS app, a.state, a.wait_event_type || ':' || coalesce(a.wait_event, '') AS wait
FROM tree t JOIN pg_stat_activity a ON a.pid = t.pid
ORDER BY t.path;

На очереди из трёх сеансов запрос показал корень - S2 в состоянии idle in transaction, под ним S3 (Lock:transactionid) и S1 (Lock:tuple). Полная версия в архиве (lock_tree.sql) дополнительно выводит сеансы неразорванного цикла с пометкой «цикл»: при deadlock_timeout = 10s в снимок попали оба участника. Корень цикла найти нельзя, у цикла его нет.

Распространённый вариант такого запроса соединяет pg_locks ожидающего и держащего по всем полям и потом рекурсивно наращивает цепочку. Я запустила его на той же очереди. Корневого сеанса в выводе нет. Одна и та же пара ожидания вышла дважды, на глубине 1 и 2: рекурсия у этого запроса стартует сразу со всех пар ожидания.

Что делает платформа при записи набора

Первый вариант серии - записать движения без всякой явной блокировки, только Набор.Записать(). Строки 5 товаров в каждом из 2000 документов шли в случайном порядке, 20 потоков одновременно. Ошибок - ноль.

Причина видна в технологическом журнале. На строке Набор.Записать() платформа сама ставит исключительную управляемую блокировку на все строки набора сразу:

TLOCK ... Regions=AccumRg246.DIMS,Locks='AccumRg246.DIMS Exclusive
  Period=[T"20261001000000":+] Fld247=55:...e8 Fld248=54:...ea,
  Period=[T"20261001000000":+] Fld247=55:...e8 Fld248=54:...ec, ... (все 5 строк)',
  WaitConnections=88, Context='ОбщийМодуль.ДедлокСтенд.Модуль : 119 : НовыйНабор(Ссылка, Т).Записать(Истина);'

Блокировка захватывает все комбинации измерений набора одним вызовом, поэтому порядок строк в наборе для неё не важен. В 1C:Developer Network об этом сказано так же: при записи набора записей платформа сама устанавливает управляемую блокировку.

Способы записи движений: замер

Каждый поток создавал непроведённый документ «ПродажаТовара» и в своей транзакции писал по нему расход в регистр «ТоварыНаСкладах», в обход учётного движка «Нано-УТ». Отличался только способ блокировки.

Способ записи Ошибок из 2000 Медиана, мс p95, мс
Только Набор.Записать() 0 697 1050
БлокировкаДанных на каждую строку по очереди, в порядке документа 1982 (99,1 %) 958 1560
То же после сортировки строк по номенклатуре 0 2575 2705
Одна БлокировкаДанных на все строки (ИсточникДанных), без сортировки 0 865 910
Одна блокировка на отсортированные строки (процедура с сортировкой, которую часто приводят как образец) 0 753 967
Разделяемая блокировка всех строк, потом исключительная; строки отсортированы 1894 (94,7 %) 252 371

Текст каждой ошибки - «Конфликт блокировок при выполнении транзакции: Неустранимый конфликт блокировок»; событий TDEADLOCK в журнале столько же, сколько ошибок (3876). После каждого прогона остаток каждого товара равен начальному 1 000 000 минус число успешных документов: откаты не оставили частичных движений.

Что из этого следует:

  1. Взаимоблокировка появляется, когда транзакция захватывает ресурсы по частям. При построчной блокировке в порядке документа одна транзакция может держать, например, «Товар 03» и ждать «Товар 01», а другая - наоборот. Из 2000 документов прошли 18.
  2. Сортировка помогает только при таком захвате по частям. С отсортированными строками ошибок не стало, но медиана выросла с 958 до 2575 мс: транзакции встали в очередь на первом общем товаре и держат его всё время своей работы.
  3. Одна блокировка на весь набор работает без сортировки. Ни одной ошибки при случайном порядке строк, как и у самой платформы при Записать(). Сортировка перед такой блокировкой на результат не влияет.
  4. Сортировка не спасает от повышения блокировки. Две транзакции берут разделяемую блокировку на одни и те же товары (например, читают остатки для контроля), потом обе просят исключительную - и ждут друг друга при любом порядке строк. 94,7 % ошибок. Документация PostgreSQL и 1C:Developer Network советуют на этот случай одно и то же: первой брать блокировку того режима, который понадобится для изменения.

Что видит пользователь

Обработка стенда открывает второй сеанс фоновым заданием: он берёт «Товар 02», затем «Товар 01», а текущий сеанс - «Товар 01», затем «Товар 02».

Рис. 3. Тонкий клиент «Нано-УТ»: обработка показывает текст ошибки платформы

Если исключение сервера не перехвачено в форме, клиент показывает только общее окно «К сожалению, возникла непредвиденная ошибка», а текст про конфликт блокировок спрятан за ссылкой «Сформировать отчет об ошибке».

Рис. 4. То же без перехвата исключения: стандартное окно ошибки

Кнопка «Товары в одном порядке» проводит тот же опыт с одинаковым порядком: второй сеанс ждёт, ошибки нет. Ждать он может долго: таймаут ожидания управляемой блокировки в базе по умолчанию 20 секунд (ПолучитьВремяОжиданияБлокировкиДанных() вернула 20), после чего ожидание прерывается с «Превышено максимальное время ожидания предоставления блокировки».

Рис. 5. Одинаковый порядок: блокировки получены после ожидания, ошибки нет

Технологический журнал: что ловить и в каких единицах

Для разбора взаимоблокировок управляемого режима нужны три события:

  • TDEADLOCK - менеджер блокировок 1С обнаружил цикл;
  • TTIMEOUT - ожидание прервано по таймауту;
  • TLOCK - установка управляемой блокировки; длинные ожидания показывают, кто кого держит (WaitConnections).
Xml UTF-8 фрагмент
1
2
3
4
5
6
7
8
9
10
11
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="C:\TJ\deadlocks" history="72">
<event><eq property="name" value="TDEADLOCK"/></event>
<event><eq property="name" value="TTIMEOUT"/></event>
<event>
<eq property="name" value="TLOCK"/>
<ge property="duration" value="30000"/>
</event>
<property name="all"/>
</log>
</config>

Порог 30000 здесь означает 3 секунды. В фильтре logcfg.xml длительность задаётся в сотнях микросекунд, а в самих записях журнала пишется в микросекундах. Я проверила это на стенде: держала блокировку 4,5 секунды. Журнал с порогом 30000 записал TLOCK с длительностью 3 921 981 мкс. Журнал с порогом 3000000 за весь день не записал ни одного TLOCK. 3000000 - это 300 секунд, больше таймаута 20 с, так что такое ожидание не наступит никогда. События TDEADLOCK этот фильтр по длительности не затрагивает, они записались все 3908.

Рис. 6. Запись TDEADLOCK: пары соединений, пространство AccumRg246.DIMS, значения измерений и стек вызова

У TDEADLOCK два содержательных свойства:

  • DeadlockConnectionIntersections - пары соединений цикла: кто кого ждёт, в каком пространстве (AccumRg246.DIMS), в каком режиме и на каких значениях измерений (Fld247 - склад, Fld248 - номенклатура; ссылка записана как номер типа и её значение);
  • Context - стек встроенного языка до Заблокировать().

Текста SQL в этом событии нет: до СУБД дело ещё не дошло.

Как записывать движения

Код варианта «одна блокировка на все строки» из модуля стенда; в серии с ним не упал ни один документ. Транзакцию открывает вызывающий: в документе это обработка проведения.

BSL UTF-8 фрагмент
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Процедура ЗаблокироватьВсе(Т, Режим)
	Б = Новый БлокировкаДанных;
	Э = Б.Добавить("РегистрНакопления.ТоварыНаСкладах");
	Э.Режим = Режим;
	Э.ИсточникДанных = Т;
	Э.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
	Э.ИспользоватьИзИсточникаДанных("Склад", "Склад");
	Б.Заблокировать();
КонецПроцедуры

// ...внутри транзакции:
ЗаблокироватьВсе(Т, РежимБлокировкиДанных.Исключительный);
// здесь, уже под исключительной блокировкой, можно читать остатки для контроля
НовыйНабор(Ссылка, Т).Записать(Истина);

Две детали, которые я нашла, проверяя на стенде процедуру с сортировкой:

  • Процедура в общем модуле с директивой &НаСервере перед ней проходит /CheckModules без ошибок, а при вызове платформа отвечает «Метод объекта не обнаружен». В общем модуле директивы компиляции перед процедурой не нужны: где он компилируется, задают его свойства.
  • Вне транзакции Блокировка.Заблокировать() выдаёт «Использование блокировки допустимо только внутри транзакции в режиме управляемых блокировок!».

Предельный случай: одна блокировка на всё проведение

В «Нано-УТ 2.0» учётный движок при каждом проведении берёт одну исключительную блокировку на служебный ключ учёта (РегистрСведений.БлокировкаУчета) и пересчитывает хронологию. Я провела им 100 документов в 20 потоков. Взаимоблокировок не было ни одной: два проведения просто не могут идти одновременно. Цена - очередь: медиана 14,2 секунды на документ, и 14 документов из 100 не дождались блокировки за таймаут базы (20 секунд, см. выше; «Превышено максимальное время ожидания предоставления блокировки»).

Для учебной базы это осознанный выбор, для рабочей базы с десятками операторов - нет. Между «каждая строка своей блокировкой» и «одна блокировка на всё» стоит рабочий вариант из таблицы выше: одна блокировка на строки своего документа.

Практические правила

  • Брать управляемую блокировку на все строки документа одним вызовом Заблокировать() и до чтения остатков. Блокировка по строке в цикле - главный источник взаимоблокировок в замере.
  • Сразу брать исключительный режим, если данные будут изменены. Разделяемая блокировка с последующей исключительной даёт взаимоблокировки при любом порядке строк.
  • Сортировать строки имеет смысл, только если захват по частям неизбежен (например, блокировки в разных процедурах одной транзакции). Тогда порядок должен быть одинаковым во всех документах, которые пишут в этот регистр.
  • Не делать долгих расчётов под блокировкой. В нашем замере при построчной блокировке отсортированных строк пауза в 20 мс под блокировкой подняла медиану документа из 5 строк с 958 мс до 2,6 секунды: транзакции стояли в очереди.
  • Ловить TDEADLOCK, TTIMEOUT и длинные TLOCK в технологическом журнале, порог для TLOCK задавать в сотнях микросекунд.
  • Искать корень очереди в PostgreSQL через pg_blocking_pids(); если в базе 1С виден ERROR: deadlock detected, транзакции захватывали строки СУБД без управляемых блокировок (автоматический режим или прямые запросы).

Что не проверялось

Автоматический режим блокировок; база 1С на PostgreSQL 16 сборки для 1С (у нас Postgres Pro 1C 17.10, PostgreSQL 16.15 - только для опыта без 1С); сервер 1С на Linux; типовые конфигурации (УТ 11, ERP); регистры с разделением итогов; документы длиннее 5 строк и нагрузка больше 20 потоков.

Итог

  • В управляемом режиме взаимоблокировки на стенде находил менеджер блокировок 1С (TDEADLOCK, «Неустранимый конфликт блокировок»); PostgreSQL за 12 000 документов не выдал ни одного deadlock detected.
  • Причина взаимоблокировок - захват по частям: построчная блокировка в порядке документа (99,1 % ошибок) и повышение разделяемой блокировки до исключительной (94,7 %).
  • Набор.Записать() и одна БлокировкаДанных на весь набор блокируют все строки сразу и не дают взаимоблокировок при любом порядке строк; сортировка нужна только построчному захвату и превращает ошибки в очередь.
  • В PostgreSQL ждут блокировку транзакции (ShareLock на transactionid); RowExclusiveLock в цикле не участвует. Корень очереди показывает pg_blocking_pids().
  • Порог TLOCK в logcfg.xml задаётся в сотнях микросекунд: 30000 - 3 секунды, 3000000 - 300 секунд.

Источники

  • PostgreSQL 16, раздел 13.3 «Explicit Locking» (табличные и строковые блокировки, взаимоблокировки, единый порядок захвата): https://www.postgresql.org/docs/16/explicit-locking.html
  • PostgreSQL 16, параметр deadlock_timeout: https://www.postgresql.org/docs/16/runtime-config-locks.html
  • PostgreSQL 16, функция pg_blocking_pids: https://www.postgresql.org/docs/16/functions-info.html
  • 1C:Developer Network, «Transaction Lock Management» (управляемый режим, блокировка при записи набора записей): https://1c-dn.com/1c_enterprise/transaction_lock_management/
  • 1C:Developer Network, «Avoiding deadlocks» (единый порядок доступа, блокировка на изменение при чтении): https://1c-dn.com/library/avoiding_deadlocks/
  • Руководство администратора 1С:Предприятия 8.3, logcfg.xml: https://kb.1ci.com/1C_Enterprise_Platform/Guides/Administrator_Guides/1C_Enterprise_8.3.23_Administrator_Guide/Appendix_3._Description_and_location_of_internal_files/3.23._logcfg.xml/3.23.1._General_description

Файл к статье

Архив pg-deadlock-stand-companion.zip (стенд от 21.10.2026):

  • pg/pg_deadlock_demo.py и pg/lock_tree.sql - опыт на PostgreSQL без 1С, нужен только Docker и Python 3;
  • 1c/config - XML-выгрузка конфигурации стенда («Нано-УТ 2.0» с модулем ДедлокСтенд и обработкой СтендВзаимоблокировок);
  • скрипты загрузки (designer.py), серии (run-series.ps1), сводки (analyze.py) и снимков клиента;
  • logcfg.xml с порогом TLOCK 3 секунды;
  • evidence - журналы и таблицы этого прогона, образцы событий TDEADLOCK и TLOCK, рисунки статьи.

В README.md - порядок запуска: свой экземпляр кластера от обычного пользователя, база на PostgreSQL для 1С, загрузка выгрузки, серия из 32-битного PowerShell через V83.COMConnector. Архив проверен из чистой распаковки: опыт на PostgreSQL повторён, выгрузка загружена в новую серверную базу, короткая серия дала тот же результат.

 
Нинель Адольевна Щербакова
Нинель Адольевна Щербакова (Ninel_S)
Архитектор • SRE & DevOps инженер • HighLoad 1С
Автор технических публикаций на Infostart. Разработчик NOPik, SRE-Suite-for-1C и мультиагентных ассистентов для экосистемы 1С:Предприятие.

Вступайте в нашу телеграмм-группу Инфостарт

1С:Предприятие PostgreSQL Блокировки Регистры накопления Технологический журнал Нано-УТ

См. также

HighLoad оптимизация Разработчик 1С 8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Использование оператора «В» для полей или данных составного типа (например, Регистратор) может приводить к неочевидным проблемам.

10.11.2025    15871    ivanov660    48    

58

HighLoad оптимизация Разработчик 1С:Предприятие 8 1C:ERP Бесплатно (free)

Приведем примеры использования различных в динамических списках и посмотрим, почему это плохо.

18.02.2025    16479    ivanov660    39    

62

HighLoad оптимизация Технологический журнал Системный администратор Разработчик Бесплатно (free)

Обсудим поиск и разбор причин длительных серверных вызовов CALL, SCALL.

24.06.2024    19107    ivanov660    13    

64

Администрирование СУБД 1С:Предприятие 8 1C:Бухгалтерия Россия Бесплатно (free)

При хранении файлов в томах на диске они иногда исчезают. Разбираемся, почему.

23.05.2024    23385    human_new    22    

61

Администрирование СУБД Системный администратор Разработчик Бесплатно (free)

Казалось бы, базовое знание: «индексы надо обслуживать, чтобы запросы выполнялись быстро». Но обслуживание индексов выполняется долго и может мешать работе пользователей. Кроме того, в последнее время популярны разговоры о том, что индексы можно вообще не обслуживать – насколько это оправданно? Рассмотрим: на что влияет обслуживание индексов, когда надо и когда не надо его выполнять, и если надо – как это сделать так, чтобы никому не помешать?

16.01.2024    33906    Филин    17    

60
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Vasvas05 27 22.10.26 20:24 Сейчас в теме
Можете поделиться промтом для ИИ чтобы такие красивые делать отчеты?
2. Ninel_S 214 22.10.26 20:26 Сейчас в теме
(1)Да, конечно. О каком именно отчете идет речь?
3. Vasvas05 27 23.10.26 18:16 Сейчас в теме
(2) неправильно выразился, я имел ввиду про публикацию, разделы выделены внутри кратко описано, красиво смотрится
4. Ninel_S 214 23.10.26 18:26 Сейчас в теме
(3) Я пришлю Вам промпт-дизайн-систему, как только буду за рабочим местом
Vasvas05; +1 – Ответить
5. Gilev.Vyacheslav 1924 24.10.26 10:44 Сейчас в теме
(4) к черту pg, напишите сюда ту часть промта, которая делала оформление
6. Ninel_S 214 24.10.26 12:38 Сейчас в теме
(5) Специально для такого известного и уважаемого мужчины, как Вы, Вячеслав, я подготовлю в ближайшее время статью с архивом, где будет всё необходимое для желающих оформлять свои статьи в индивидуальном авторском стиле.
А пока, не стесняйтесь ставить даме "плюсики".
С пламенным приветом, Ваш читатель и почитатель
Нинель Адольевна Щербакова.

Кстати, в "подвале" каждой моей статьи есть ссылка на мои репозитории на GitHub, где описана моя дизайн-система.
7. Ninel_S 214 24.10.26 15:30 Сейчас в теме
(5) Кстати, на странице http://www.gilev.ru/postgresql/ прежде лежала книга «Технологические вопросы крупных внедрений 1С:Предприятие 8»? Или память моя мне изменяет?
8. Gilev.Vyacheslav 1924 24.10.26 19:15 Сейчас в теме
(7)
лежала

не лежала
9. Ninel_S 214 25.10.26 18:19 Сейчас в теме
(1) https://nickscherbakov.github.io/ninel-s-articles-tracker/design-system.html?v=2.0.0

Пользуйтесь на здоровье

(Если что-то не получается - пишите, поможем)
Vasvas05; +1 – Ответить
10. Vasvas05 27 27.10.26 15:44 Сейчас в теме
(9) спасибо, круто))) и красиво
Для отправки сообщения требуется регистрация/авторизация