Кто кого ждёт: разбор ошибки блокировки транзакции в 1С 8.3 от журнала до кода

· 11 мин

Содержание

Ошибка Конфликт блокировок при выполнении транзакции значит одно: ваша операция хотела изменить данные, которые в этот момент держала другая транзакция, и не дождалась их освобождения. Разовый сбой лечится повтором операции через минуту. Если ошибка повторяется каждый день, ищут виновника: сначала в журнале регистрации, затем в технологическом журнале по событиям TLOCK, TTIMEOUT и TDEADLOCK, а исправляют код, расписание тяжёлых операций или настройки СУБД.

Выбор пути зависит от масштаба. Один пользователь раз в неделю — хватит журнала регистрации и разговора с коллегой, который в ту же минуту закрывал месяц. Десятки ошибок в день на сервере — без технологического журнала не обойтись. Файловая база с пятью бухгалтерами — повод думать о переходе на клиент-серверный вариант.

Откуда берётся конфликт блокировок в платформе 8.3

Любая запись в базу 1С идёт внутри транзакции: проведение документа, запись справочника, регламентная операция . Чтобы два сеанса не испортили одни и те же остатки, платформа блокирует данные на время транзакции. Второй сеанс, которому нужны те же данные, встаёт в очередь.

Ожидание не бесконечно. Если блокировку не отпустили за отведённое время, платформа отменяет транзакцию ожидающего и выдаёт ошибку. Для управляемых блокировок время ожидания по умолчанию — 20 секунд.

Как выглядит текст ошибки в разных ситуациях:

  • 🔒 Конфликт блокировок при выполнении транзакции: Превышено максимальное время ожидания предоставления блокировки — управляемая блокировка, классический случай очереди.
  • 🔁 Сообщение со словами о взаимоблокировке (deadlock) — два сеанса держат по куску данных и ждут друг друга. Платформа или СУБД снимает одну из транзакций, не дожидаясь тайм-аута.
  • 🗄️ Конфликт блокировок при выполнении транзакции: и далее текст от СУБД, например Lock request time out period exceeded — блокировка на уровне MS SQL Server, а не менеджера 1С.

Есть похожая ошибка Не удалось записать: объект уже заблокирован (или близкая по смыслу). Это другая история: объектная блокировка, когда тот же документ открыт на редактирование у другого пользователя. Транзакции там ни при чём, достаточно найти, у кого открыта форма.

Режимы блокировок конфигурации

Поведение зависит от свойства конфигурации Режим управления блокировкой данных в транзакции:

РежимКто блокируетГде обычно встречается
АвтоматическийСУБД сама ставит блокировки при чтении и записиСтарые и самописные конфигурации
УправляемыйМенеджер блокировок 1С по указанию кодаТиповые БП 3.0, ЗУП 3.1, УТ 11, ERP
Автоматический и управляемыйРежим задаётся у каждого объектаПереходные доработанные конфигурации

В управляемом режиме блокируются только те записи, которые код явно заблокировал. В автоматическом СУБД может заблокировать заметно больше — диапазоны записей и целые таблицы, — и конфликты возникают чаще.

Первая диагностика по журналу регистрации

Журнал регистрации есть в любой базе, включать ничего не нужно. В БП 3.0 и ЗУП 3.1 он открывается через Администрирование → Обслуживание → Журнал регистрации, в Конфигураторе — через Администрирование → Журнал регистрации.

Порядок поиска:

  1. Откройте журнал и задайте отбор по периоду: 10–15 минут вокруг времени ошибки.
  2. В отборе укажите уровень «Ошибка».
  3. Найдите записи с событием Транзакция. Отмена и текстом ошибки в комментарии.
  4. Запомните пользователя, компьютер и объект, на котором упала транзакция.
  5. Снимите отбор по уровню и посмотрите, что в ту же минуту делали другие пользователи: проводили документы того же вида, закрывали месяц, загружали обмен.

Типичные пары «пострадавший — виновник», которые видно уже на этом шаге:

  • 📦 Кладовщик проводит реализацию, бухгалтер в это же время перепроводит документы за месяц.
  • 🔄 Регламентное задание обмена загружает пакет документов, пользователи проводят документы по тем же складам.
  • 📊 Закрытие месяца или расчёт зарплаты запущены в рабочее время.
  • 🧾 Групповая обработка документов (перезаполнение, перепроведение) работает одной большой транзакцией.

Если журнал регистрации показывает ошибки только у одного человека и только при одной операции, начните с вопроса, что ещё он запускает параллельно. Нередко «виновник» — тот же пользователь во втором сеансе.

Ограничение журнала: он показывает, кто упал, но не показывает, кого именно ждал сеанс. Для этого нужен технологический журнал.

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

Технологический журнал (ТЖ) — это текстовые логи сервера 1С и клиента. Настраивается файлом logcfg.xml. На Windows его кладут в каталог C:\Program Files\1cv8\conf\ — так настройка действует для всех установленных версий платформы. Платформа перечитывает файл примерно раз в минуту, перезапуск службы не нужен.

Минимальная настройка для разбора блокировок:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
  <log location="D:\techlog\locks" history="24">
    <event>
      <eq property="name" value="TLOCK"/>
      <ne property="WaitConnections" value=""/>
    </event>
    <event>
      <eq property="name" value="TTIMEOUT"/>
    </event>
    <event>
      <eq property="name" value="TDEADLOCK"/>
    </event>
    <property name="all"/>
  </log>
</config>

Что означают события:

СобытиеЧто фиксируетГлавные свойства
TLOCKУстановку управляемой блокировки (с отбором — только с ожиданием)Regions — какие таблицы, Locks — какие поля и значения, WaitConnections — кого ждали
TTIMEOUTТайм-аут ожидания — та самая ошибка у пользователяWaitConnections — номер соединения-виновника
TDEADLOCKВзаимоблокировкуDeadlockConnectionIntersections — кто и на чём пересёкся

Включайте ТЖ с ограничением по месту и сроку хранения. Параметр history="24" хранит логи 24 часа. Без отбора TLOCK пишет каждую блокировку, и на нагруженном сервере каталог разрастается на гигабайты за день.

Как читать логи

  1. Найдите строку TTIMEOUT по времени ошибки. В ней есть свойство WaitConnections с номером соединения.
  2. Найдите в логах того же процесса события этого соединения (свойство t:connectID) за предыдущие 20–30 секунд.
  3. По свойствам Usr и Context определите пользователя и строку кода, которая держала блокировку.
  4. В Regions посмотрите таблицу: например, AccumRg12345.DIMS — регистр накопления.

Имена таблиц ТЖ переводятся в объекты конфигурации функцией ПолучитьСтруктуруХраненияБазыДанных() — её вызывают из внешней обработки или консоли кода. Для разбора больших объёмов логов удобны готовые анализаторы ТЖ; на сервере без них выручает поиск через PowerShell:

Get-ChildItem D:\techlog\locks -Recurse -Filter *.log |
  Select-String -Pattern "TTIMEOUT|TDEADLOCK" |
  Select-Object -First 50

Исправление кода и запросов: где рождаются долгие блокировки

Если ТЖ показывает, что блокировку держал ваш код (доработка, обработка, расширение), почти всегда причина в одном из пунктов ниже.

Слишком долгая транзакция

Блокировка живёт до конца транзакции. Проведение документа на 3 секунды почти не мешает другим. Групповая обработка на 2000 документов в одной транзакции держит остатки 10 минут, и все остальные падают по тайм-ауту.

Что делать:

  • ✂️ Дробите массовую обработку: одна транзакция на документ или на пачку из 50–100.
  • 🚫 Не вызывайте внутри транзакции диалоги, Вопрос(), обращения к внешним сервисам и чтение файлов.
  • 🐢 Выносите тяжёлые вычисления до НачатьТранзакцию(), внутри оставляйте только запись.

Блокируется больше, чем нужно

Управляемую блокировку ставят точно по измерениям, которые меняет документ:

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

Без строк ИспользоватьИзИсточникаДанных код заблокирует весь регистр: два документа по разным складам и разному товару будут ждать друг друга.

Взаимоблокировки из-за порядка

Deadlock в 1С чаще всего возникает по схеме «сначала прочитал с разделяемой блокировкой, потом пытаюсь записать». Два сеанса одновременно читают остатки, оба держат разделяемую блокировку, оба хотят исключительную — и ждут друг друга.

Правила, которые снимают большую часть взаимоблокировок:

  1. Ставьте исключительную блокировку до чтения данных, которые потом будете менять.
  2. Блокируйте ресурсы в одном и том же порядке во всех документах: например, сначала регистр остатков, потом регистр взаиморасчётов.
  3. Не смешивайте в одной транзакции запись объекта и последующую перезапись того же объекта.

Медленный запрос внутри транзакции

Запрос без подходящего индекса читает таблицу целиком. В автоматическом режиме или на уровне СУБД это значит блокировку большого диапазона записей. Признаки и лекарства:

  • 🔍 Отбор по реквизиту, который не индексирован, — включите у реквизита свойство Индексировать.
  • 🧮 Виртуальная таблица остатков с отбором в ГДЕ, а не в параметрах — перенесите условие в параметры виртуальной таблицы.
  • 🔗 Соединение с подзапросом без индекса — замените подзапрос временной таблицей с ИНДЕКСИРОВАТЬ ПО.

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

Настройки СУБД и сервера 1С против конфликтов блокировок

Если код типовой и не менялся, а ошибки растут вместе с базой, смотрите на окружение.

Время ожидания блокировки

В Конфигураторе: Администрирование → Параметры информационной базы — поле времени ожидания блокировки данных в секундах. Из кода то же значение меняют методом УстановитьВремяОжиданияБлокировкиДанных().

Увеличение с 20 до 40–60 секунд уменьшает число ошибок, но не убирает причину: пользователи будут дольше ждать «зависшую» программу. Используйте это как временную меру, пока ищете виновника.

MS SQL Server

  • 📈 Статистика и индексы. Устаревшая статистика заставляет СУБД выбирать полный просмотр таблиц. Регламент: ежедневное обновление статистики, еженедельная реорганизация или перестроение индексов в нерабочее время.
  • 🧱 Эскалация блокировок. При большом числе строковых блокировок SQL Server поднимает их до блокировки таблицы. Для баз 1С часто включают флаг трассировки 1224, отключающий эскалацию по числу блокировок. Решение принимает администратор СУБД после тестов.
  • 📸 Версионное чтение. Для управляемого режима платформа 8.3 использует на MS SQL режим READ_COMMITTED_SNAPSHOT, и чтение не блокирует запись. Проверить:
SELECT name, is_read_committed_snapshot_on
FROM sys.databases
WHERE name = N'buh_base';

Если значение 0, а конфигурация работает в управляемом режиме, ищите причину: база могла быть перенесена скриптами в обход платформы.

PostgreSQL

На PostgreSQL чтение и так не блокирует запись. Конфликты там почти всегда на стороне 1С (управляемые блокировки) или из-за долгих транзакций. Полезно включить log_lock_waits = on в postgresql.conf, чтобы СУБД писала в лог ожидания дольше значения deadlock_timeout.

Сервер 1С

  • ⏰ Регламентные задания. Обмены, загрузка курсов и пересчёт итогов, запущенные одновременно, конкурируют с пользователями. Разнесите расписания, тяжёлые задания переведите на ночь.
  • 🖥️ Нехватка ресурсов. Если рабочие процессы упираются в процессор или память, транзакции длятся дольше, а очередь блокировок растёт. Смотрите загрузку в консоли администрирования кластера и в мониторинге ОС.
  • 👥 Сеансы-зомби. Зависший сеанс может держать транзакцию открытой. Найти его помогает список сеансов информационной базы в консоли администрирования серверов.

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

Блокировки в файловой базе и на сетевом диске

В файловом варианте нет сервера и СУБД. Блокировки ставятся на уровне целых таблиц через файл 1Cv8.1CD. Пока один пользователь проводит реализацию, второй не может записать ничего в те же таблицы — даже по другому складу.

Отсюда признаки, характерные именно для файловой базы:

  • 👥 Ошибки растут при каждом новом пользователе, который проводит документы одновременно с остальными.
  • 🌐 База лежит в сетевой папке, и при медленной сети транзакции длятся дольше.
  • 🛡️ Антивирус проверяет 1Cv8.1CD при каждом обращении и задерживает запись.
  • 💾 База на NAS-хранилище или в облачной синхронизируемой папке — ненадёжный вариант для совместной работы.

Что помогает:

  1. Добавьте каталог базы в исключения антивируса на сервере и на рабочих местах.
  2. Держите базу на быстром локальном диске сервера, а не на пользовательском компьютере.
  3. Публикуйте файловую базу на веб-сервере: обращения к файлу идут с одного компьютера, а не со всех по сети.
  4. Тяжёлые операции (закрытие месяца, перепроведение) запускайте, когда в базе нет других пользователей.
  5. Если одновременно активно работают больше 5–7 человек, планируйте переход на клиент-серверный вариант с СУБД.

Профилактика: мониторинг блокировок без аварий

Разовый разбор устраняет текущую проблему. Чтобы новые конфликты не накапливались, нужен постоянный контроль.

  • 📅 Раз в неделю смотрите журнал регистрации с отбором по событию Транзакция. Отмена. Рост числа записей — первый сигнал.
  • 📝 Держите облегчённый ТЖ постоянно: только TTIMEOUT и TDEADLOCK, хранение 72 часа. Он почти не нагружает сервер, а при жалобе у вас уже есть логи.
  • 🗓️ Согласуйте регламент: закрытие месяца, расчёт зарплаты, массовое перепроведение — вне рабочего времени или в «тихие» часы.
  • 🧪 Каждую доработку, которая пишет в регистры, проверяйте на тестовой копии под нагрузкой хотя бы двух сеансов.
  • 📊 Для крупных баз используйте специализированные средства мониторинга производительности 1С, которые собирают ТЖ и строят графики ожиданий.

Для быстрого определения своего случая:

Диагностика: выберите симптом

Частые вопросы

Теряются ли данные при конфликте блокировок?
Нет. Транзакция отменяется целиком: документ остаётся в состоянии до попытки записи. Повторите операцию, когда освободятся данные.
Можно ли просто отключить блокировки?
Нет. Без блокировок два сеанса одновременно спишут один и тот же остаток, и учёт разойдётся. Лечат длительность и объём блокировок, а не их наличие.
Почему ошибка появилась после обновления конфигурации?
Новый релиз мог изменить алгоритм проведения или добавить регламентные задания. Проверьте расписание новых заданий и сравните ТЖ до и после обновления на одной и той же операции.
Помогает ли перезапуск сервера 1С?
Временно: перезапуск обрывает все сеансы и снимает все блокировки. Причина остаётся, и ошибка возвращается. Перезапуск — только в нерабочее время и с предупреждением пользователей.
Чем объектная блокировка отличается от транзакционной?
Объектная ставится, когда пользователь открыл объект на редактирование, и держится до закрытия формы. Транзакционная живёт секунды, только пока идёт запись в базу.