Разбор от сообщества: Ваш журнал показывает deadlock. Разбираемся | infolimp.ru

Разбор от сообщества: Ваш журнал показывает deadlock. Разбираемся

21 августа 2026 · infolimp.ru

Deadlock в журнале регистрации — ситуация, когда система зависает без видимых причин, а в окне «Состояние выполнения» — пустота. Разработчики с 10-летним стажем годами не сталкиваются, пока не попадают в проект с высокой конкурентной нагрузкой. Мы разберём механику блокировок внутри ЗаписьЖурналаРегистрации, покажем, как воспроизвести deadlock, и дадим конкретные инструменты для диагностики. Материал основан на реальном случае из сообщества — ссылка на источник в начале.

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

Многие считают, что вызов ЗаписьЖурналаРегистрации — атомарная операция, не подверженная блокировкам. Это не так. Внутри платформы журнал регистрации хранится в служебных таблицах, и при конкурентной записи в пределах одной транзакции возникает традиционный конфликт блокировок.

Как возникает deadlock: пошаговое воспроизведение

Представьте два параллельных сеанса, каждый из которых выполняет длительную транзакцию с записью в журнал. Если оба сеанса одновременно вызывают ЗаписьЖурналаРегистрации, а затем пытаются получить доступ к одним и тем же данным, SQL-сервер (или встроенная СУБД) вынужден разрешить взаимоблокировку, выбирая жертву. В итоге один из сеансов получает ошибку, а другой — продолжает работу, но состояние системы становится неконсистентным.

// Пример кода, который может привести к deadlock
Процедура ОбработатьПакетДанных(Пакет)
    НачатьТранзакцию();
    Попытка
        // Работа с данными
        Для Каждого Строка Из Пакет Цикл
            // ... обновление регистров ...
        КонецЦикла;
        
        // Запись в журнал внутри той же транзакции
        ЗаписьЖурналаРегистрации("Обработка", УровеньЖурналаРегистрации.Информация,
            , , "Обработан пакет из " + Пакет.Количество() + " записей");
        
        // Долгая операция, увеличивающая время блокировки
        ВыполнитьДополнительныеРасчеты();
        
        ЗафиксироватьТранзакцию();
    Исключение
        ОтменитьТранзакцию();
        ЗаписьЖурналаРегистрации("Ошибка", УровеньЖурналаРегистрации.Ошибка,
            , , КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
    КонецПопытки;
КонецПроцедуры

Ключевой тезис: Deadlock в журнале регистрации — это не баг платформы, а следствие неправильного проектирования: длинная транзакция + запись в общий ресурс (журнал) = гарантированный конфликт при масштабировании.

Анализ типичных сценариев

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

Сценарий 1: Массовые операции в фоне

Фоновое задание загружает 100 000 строк из Excel и на каждую строку пишет в журнал. Если запустить два таких задания параллельно, они начнут конкурировать за запись в служебную таблицу. При этом время транзакции может достигать нескольких минут — блокировка удерживается всё это время.

Сценарий 2: Запись в журнал внутри транзакции с «тяжёлыми» вычислениями

Типичная ошибка — помещать вызов ЗаписьЖурналаРегистрации внутрь транзакции, которая содержит ещё и расчёты себестоимости или перепроведение документов. В такой ситуации блокировка журнала превращается в узкое место.

Подход Условия применимости Риск deadlock
Запись в журнал внутри транзакции Низкая конкурентность, короткие транзакции Высокий при более 2–3 параллельных сеансов
Запись в журнал после фиксации транзакции Всегда, если не требуется атомарность Низкий
Асинхронная запись через отдельный фоновый процесс Высокая нагрузка, большие объемы Минимальный

Диагностика и инструменты

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

Приём 1: Трассировка через замер производительности

Включите замер производительности (Сервис → Параметры → Замер производительности) и ловите событие «Транзакция заблокирована». Это покажет, какой объект участвует в блокировке. Однако внутри платформы имя таблицы журнала не отображается — только «Служебная таблица», что уже указывает на проблему.

Приём 2: Искусственное воспроизведение в тестовой среде

Напишите скрипт, который запускает в двух сеансах одну и ту же процедуру с ЗаписьЖурналаРегистрации внутри транзакции и искусственной задержкой. Если в рабочей среде вы видите падение, проводите тест на копии базы с реальными данными.

// Пример для тестирования: два сеанса выполняют одновременно
Процедура ТестDeadlock()
    НачатьТранзакцию();
    ЗаписьЖурналаРегистрации("Тест", УровеньЖурналаРегистрации.Информация, , , "Начало");
    // Имитация долгой работы
    Для Инд = 1 По 1000000 Цикл
        // Пустой цикл
    КонецЦикла;
    ЗаписьЖурналаРегистрации("Тест", УровеньЖурналаРегистрации.Информация, , , "Конец");
    ЗафиксироватьТранзакцию();
КонецПроцедуры
// Получение информации об ошибке после отлова
Процедура ОбработчикОшибки()
    ЗаписьЖурналаРегистрации("Deadlock", УровеньЖурналаРегистрации.Ошибка,
        , , КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
    // Не записывайте в журнал внутри транзакции — вызов будет вне транзакции
КонецПроцедуры

Предупреждение: Никогда не вызывайте ЗаписьЖурналаРегистрации внутри обработчика исключения, если текущая транзакция ещё не отменена. Это может привести к повторному deadlockу.

Что делать прямо сейчас: чек-лист и типичные ошибки

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

Чек-лист для проверки существующего кода

  1. Найти все вызовы ЗаписьЖурналаРегистрации — используйте поиск по конфигурации (Ctrl+Shift+F).
  2. Проверить, находятся ли они внутри НачатьТранзакцию()…ЗафиксироватьТранзакцию() — если да, переместите вызов после фиксации (или перед началом, если это не критично).
  3. Для фоновых заданий — используйте отдельный фоновый процесс для записи лога, который не участвует в основной транзакции.
  4. Настроить изоляцию транзакций — на уровне SQL-сервера включите READ COMMITTED SNAPSHOT (только для SQL Server). Это снизит конкуренцию за чтение, но не устранит deadlock при записи.
  5. Мониторить длительность транзакций — через стандартный отчёт «Анализ активности» или через внешние инструменты (например, SQL Profiler).

Типичные ошибки

Расширение «НОПик» для 1С — встраиваемый коннектор к внешнему AI с интеллектуальным поиском по базе. Задавайте вопросы обычными словами - AI сам найдёт нужное. 45 дней бесплатно.

Попробовать НОПик →
Знаете ответ на такие вопросы не хуже автора статьи? Пройдите бесплатную анонимную проверку уровня на infolimp.ru - 3 практических задачи, 15 минут, публичный токен-профиль, который можно показать работодателю или заказчику. Без регистрации по почте.

Проверить свой уровень бесплатно →