1С Ошибка блокировки транзакции в СУБД (Deadlock) — Анализ и устранение
- Сообщение пользователю:
Ошибка блокировки транзакции. Взаимная блокировка (Deadlock). Конфликт блокировок при выполнении транзакции. - В технологическом журнале фиксируются события
TLOCKиDEADLOCKсо свойствомWaitConnections. - В MS SQL Profiler / Extended Events фиксируется событие
xml_deadlock_report. - В PostgreSQL фиксируется:
ERROR: deadlock detected (SQLSTATE 40P01).
1. Настройка технологического журнала (ТЖ) для локализации Deadlock
Создайте файл конфигурации ТЖ logcfg.xml в каталоге /opt/1cv8/conf/ (Linux) или C:\Program Files\1cv8\conf\ (Windows):
<config xmlns="http://v8.1c.ru/v8/tech-log">
<dump create="false"/>
<log location="/var/log/1c/logs/deadlocks" history="72">
<event>
<eq property="name" value="DEADLOCK"/>
</event>
<event>
<eq property="name" value="TLOCK"/>
<ge property="waitconnections" value="1"/>
</event>
<property name="all"/>
</log>
</config>2. Перевод конфигурации в режим управляемых блокировок
В свойствах конфигурации в Конфигураторе установите: Режим управления блокировкой данных → Управляемый (Managed Lock).
3. Упорядочивание захвата ресурсов в коде 1С
Главное правило борьбы с Deadlock — захватывать таблицы и ресурсы в едином порядке во всех транзакциях:
// 1. Сортировка строк перед блокировкой и записью в регистры
ТаблицаДвижений.Сортировать("НоменклатураСсылка, СкладСсылка Возр");
// 2. Явный захват управляемой блокировки
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиТоваров");
ЭлементБлокировки.ИсточникДанных = ТаблицаДвижений;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "НоменклатураСсылка");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();4. Тюнинг параметров СУБД
- MS SQL: Активируйте версионирование строк:
ALTER DATABASE ib_database SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE; ALTER DATABASE ib_database SET ALLOW_SNAPSHOT_ISOLATION ON; - PostgreSQL: Проверьте параметр
deadlock_timeout = 1000msвpostgresql.conf.
Частые вопросы (FAQ)
В чем физическая суть Deadlock (взаимной блокировки)?
Deadlock возникает, когда Транзакция 1 заблокировала Ресурс A и ожидает освобождения Ресурса B, а Транзакция 2 одновременно заблокировала Ресурс B и ожидает Ресурс A. СУБД распознает циклическое ожидание и аварийно прерывает одну из транзакций (victim transaction).
Почему включение READ_COMMITTED_SNAPSHOT решает проблему блокировок?
Опция RCSI включает неблокирующее чтение: операции SELECT читают снимок данных из tempdb, не накладывая разделяемых S-блокировок, что исключает конфликты между читателями и писателями.
Чем управляемый режим блокировок 1С отличается от автоматического?
В автоматическом режиме блокировками управляет СУБД через уровень изоляции Serializable/Repeatable Read (крупные блокировки диапазонов Range-locks). В управляемом режиме блокировки ставятся на уровне сервера 1С только на конкретные значения измерений.
Как уменьшить длительность транзакции в коде 1С?
Выносите все тяжелые расчеты, запросы и подготовку данных за пределы транзакции до вызова метода НачатьТранзакцию() / Записать(), оставляя внутри блока только физическую запись подготовленных движений.