Ошибка «Конфликт блокировок при выполнении транзакции»: кто держит данные и что с этим делать
Содержание
Конфликт блокировок при выполнении транзакции в 1С означает: ваш сеанс хотел изменить данные, но их уже заблокировал другой сеанс, и время ожидания истекло. Транзакция откатывается целиком, документ не проводится. Чаще всего помогает повторить операцию через минуту, а если ошибка повторяется — найти сеанс, который держит блокировку, и разбираться с ним.
Типичная картина: бухгалтер проводит реализацию в 10:15, а в это время коллега перепроводит документы за квартал или идёт загрузка из обмена. Через 20 секунд ожидания появляется сообщение об ошибке. Разовый сбой лечится повтором, регулярный — поиском того, кто держит данные.
Что означает конфликт блокировок и чем он опасен
Любая запись в 1С идёт внутри транзакции: документ, его движения по регистрам, пересчёт итогов. Чтобы два пользователя не списали один и тот же остаток, платформа блокирует данные на время транзакции. Второй сеанс, которому нужны те же данные, встаёт в очередь.
Если первый сеанс не освободил данные за отведённое время, второй получает отказ. Тексты, которые встречаются чаще всего:
- 🔒
Конфликт блокировок при выполнении транзакции: Превышено максимальное время ожидания предоставления блокировки— управляемые блокировки, ожидание истекло. - 🔒
Конфликт блокировок при выполнении транзакции: Microsoft SQL Server Native Client 11.0: Истекло время ожидания запроса на блокировку— автоматические блокировки, отказ пришёл от самой СУБД. - 🔁 Сообщение со словами
взаимоблокировкаилиdeadlock— два сеанса ждут друг друга по кругу, и СУБД или менеджер блокировок обрывает одного из них.
Не путайте с похожими ошибками другой природы:
| Сообщение | Что это | Связь с транзакцией |
|---|---|---|
| Конфликт блокировок при выполнении транзакции | Блокировка данных, ожидание истекло | Прямая |
Не удалось заблокировать объект / объект редактируется другим пользователем | Объектная пессимистическая блокировка: форма открыта на изменение | Нет, это блокировка формы |
Ошибка блокировки объекта. Объект изменён или удалён | Оптимистическая блокировка: объект перезаписали, пока он был открыт | Нет, проверка версии |
Чем опасен конфликт. Сами данные он не портит: откат транзакции возвращает базу в состояние до операции. Проблема в другом:
- ⏳ пользователи теряют время и проводят документы по нескольку раз;
- 📦 групповые обработки (закрытие месяца , перепроведение) обрываются посередине;
- 🔄 обмены и регламентные задания падают с ошибкой, и данные не доезжают;
- 📉 при постоянных конфликтах работа в базе в рабочие часы фактически встаёт.
Почему возникают конфликты блокировок в 1С
Причина всегда одна: кто-то слишком долго держит данные, нужные другим. Вопрос в том, кто и почему.
Долгие транзакции
- 🗂️ групповое перепроведение документов за большой период;
- 📅 закрытие месяца, расчёт себестоимости, расчёт зарплаты по всей организации;
- 🔄 загрузка пакета обмена (РИБ, обмен с УТ или сайтом) в рабочее время;
- ⚙️ регламентные задания: обновление цен, загрузка выписок, пересчёт итогов.
Каждая такая операция держит блокировки на регистрах до своей фиксации. Если она длится минуты, все остальные, кому нужны те же остатки, получают отказ.
Избыточные блокировки
- 🧱 Автоматический режим блокировок. На MS SQL платформа блокирует записи на уровне СУБД, и СУБД может укрупнить блокировку до целой таблицы. Тогда мешают даже операции по разным складам и товарам.
- 🧱 Доработанный код. Программист ставит управляемую блокировку на весь регистр, не указав поля (склад, номенклатура), — и проведение любого документа блокирует всех.
- 🧱 Отсутствие нужного индекса. Запрос внутри транзакции читает таблицу целиком и блокирует больше строк, чем нужно.
Взаимоблокировки
Сеанс А заблокировал товар 1 и ждёт товар 2, сеанс Б держит товар 2 и ждёт товар 1. Ни один не завершится сам.
Частый источник в доработках — «чтение, потом запись»: код сначала ставит разделяемую блокировку, читает остаток, а потом пытается поставить исключительную на те же данные. Два таких сеанса гарантированно сцепятся.
Особые случаи
- 💤 Сеанс «завис»: пользователь закрыл клиент некорректно, а сеанс на сервере ещё жив и держит транзакцию.
- 🗄️ Обслуживание СУБД (перестроение индексов, резервное копирование с нагрузкой) запущено днём.
- 🐌 Сервер перегружен: транзакции просто выполняются медленнее, и время ожидания кончается раньше.
Как найти виновника конфликта блокировок
Сообщение пользователя говорит только, что он не дождался. Кто держал данные — надо искать отдельно.
Шаг 1. Посмотрите активных пользователей
В режиме 1С:Предприятие откройте Администрирование → Обслуживание → Активные пользователи (в типовых БП 3.0 и ЗУП 3.1 этот раздел есть). Ищите:
- Кто сейчас запустил групповую обработку или закрытие месяца.
- Фоновые сеансы: регламентные задания, обмены.
- Сеансы с давним временем начала, которые не должны работать.
Сопоставьте время ошибки с тем, что происходило в базе. В журнале регистрации (Администрирование → Обслуживание → Журнал регистрации) отберите события за эти минуты: длинные записи и ошибки у других пользователей сразу укажут на источник.
Шаг 2. Консоль кластера (клиент-серверная база)
В консоли администрирования серверов 1С раскройте Кластер → Информационные базы → <база> → Сеансы. Добавьте в список колонки с временем вызова и данными о текущей операции, отсортируйте по длительности. Сеанс, который давно выполняет один вызов, — первый подозреваемый.
Там же, в узле базы, есть список блокировок: видно, какой сеанс и какие объекты держит.
Шаг 3. Технологический журнал
Самый точный способ. Создайте файл logcfg.xml в каталоге conf установленной платформы (например, C:\Program Files\1cv8\conf) на сервере 1С:
<?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"/>
</event>
<event>
<eq property="name" value="TTIMEOUT"/>
</event>
<event>
<eq property="name" value="TDEADLOCK"/>
</event>
<property name="all"/>
</log>
</config>
Платформа подхватывает файл без перезапуска, примерно через минуту. Что смотреть:
TTIMEOUT— событие превышения ожидания. В свойствеWaitConnectionsномер соединения, которое держало блокировку.TDEADLOCK— взаимоблокировка: какие сеансы и какие пространства (регистры) участвовали.TLOCK— все установки управляемых блокировок, с длительностью и пространством.
Журнал с property name="all" быстро растёт. Держите его включённым только на время поиска, проверяйте свободное место на диске и затем удалите logcfg.xml.
Шаг 4. Уровень СУБД
При автоматических блокировках на MS SQL смотрите ожидания в самой СУБД: монитор активности или запрос к служебным представлениям.
SELECT r.session_id, r.blocking_session_id, r.wait_type, r.wait_time, t.text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.blocking_session_id <> 0;
Для PostgreSQL аналог — представления pg_stat_activity и pg_locks. По номеру процесса СУБД соединение затем сопоставляется с сеансом 1С в консоли кластера.
Как устранить конфликт блокировок в 1С: от простого к сложному
Способ 1. Повторить операцию
Если ошибка разовая, просто проведите документ ещё раз через 1–2 минуты. Транзакция откатилась целиком, задвоения не будет.
Способ 2. Дождаться или завершить мешающий сеанс
Если виновник найден и это зависший сеанс или обработка, запущенная по ошибке:
- Свяжитесь с пользователем и попросите закончить работу.
- Если сеанс завис, завершите его в консоли кластера или в списке активных пользователей.
Завершение сеанса обрывает его транзакцию: всё, что он не успел записать, откатится. Пользователь потеряет несохранённые данные. Предупредите его заранее. Завершать рабочий процесс или перезапускать службу сервера 1С ради одного сеанса не нужно: это оборвёт работу всех.
Способ 3. Развести тяжёлые операции по времени
Самое действенное и бесплатное средство:
- 🌙 перепроведение, закрытие месяца, массовые пересчёты — вечером или в выходные;
- 🕐 регламентные задания — по расписанию вне рабочих часов (
Администрирование → Обслуживание → Регламентные и фоновые задания); - 🔄 обмены — реже и небольшими пакетами, а не одним большим раз в день в 11:00.
Способ 4. Увеличить время ожидания блокировки
В Конфигураторе: Администрирование → Параметры информационной базы, поле времени ожидания блокировки данных (по умолчанию 20 секунд). Увеличение до 40–60 секунд снимает конфликты, которые возникают на коротких пиках.
💡 Это обезболивающее, а не лечение. Длинная транзакция никуда не денется, просто пользователи будут ждать дольше. Используйте как временную меру, пока ищете причину.
Способ 5. Включить разделение итогов
У регистров накопления и бухгалтерии итоги хранятся по периодам, и все документы пишут в одни и те же строки итогов. Режим разделения итогов позволяет параллельным транзакциям писать в разные строки.
Включается в режиме Предприятия через обработку управления итогами (Все функции → Стандартные → Управление итогами) для регистров, у которых в конфигурации разрешено разделение итогов. Для типовых конфигураций это свойство обычно уже включено разработчиком.
Способ 6. Перейти на управляемый режим блокировок
Свойство конфигурации «Режим управления блокировкой данных» бывает «Автоматический», «Управляемый» и «Автоматический и управляемый». Типовые конфигурации на 8.3 (БП 3.0, ЗУП 3.1, УТ 11) работают в управляемом режиме.
Автоматический режим встречается в старых самописных и сильно доработанных базах. Перевод на управляемый — работа программиста: в каждом месте записи нужно явно поставить блокировку. Без этого после смены режима можно получить отрицательные остатки при параллельной работе.
Способ 7. Исправить код доработки
Правильная управляемая блокировка ставится до чтения остатков, только на нужные данные и сразу в исключительном режиме:
НачатьТранзакцию();
Попытка
Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ТоварыНаСкладах");
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
ЭлементБлокировки.УстановитьЗначение("Склад", Склад);
ЭлементБлокировки.ИсточникДанных = ТаблицаТоваров;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
Блокировка.Заблокировать();
// здесь чтение остатков и запись движений
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
Что здесь сделано против конфликтов:
- Блокировка ограничена полями «Склад» и «Номенклатура», а не всем регистром.
- Режим сразу исключительный: нет перехода «разделяемая → исключительная», который даёт взаимоблокировки.
- Внутри транзакции нет диалогов, запросов к внешним сервисам и долгих вычислений.
Ещё один приём практиков против взаимоблокировок: во всех документах блокировать данные в одном порядке, например по возрастанию кода номенклатуры. Тогда сеансы встают в очередь, а не в кольцо.
| Способ | Когда применять | Риск |
|---|---|---|
| Повторить операцию | Разовая ошибка | Нет |
| Завершить сеанс | Сеанс завис | Потеря несохранённых данных пользователя |
| Перенести тяжёлые операции | Ошибки в одно и то же время | Нет |
| Увеличить таймаут | Короткие пики нагрузки | Пользователи дольше ждут |
| Разделение итогов | Много параллельных проведений | Чуть медленнее отчёты по остаткам |
| Управляемый режим | Самописная база в автоматическом режиме | Ошибки в остатках при неполной доработке |
| Правка кода | Ошибки после доработки, взаимоблокировки | Нужен программист и тестирование на копии |
Файловая и клиент-серверная база: в чём разница
В файловой базе всё хранится в одном файле 1Cv8.1CD, и блокировки ставятся крупно, на таблицы целиком. Поэтому конфликт возникает даже тогда, когда два бухгалтера работают с разными складами и организациями.
Что доступно в файловом варианте:
- 👥 список активных пользователей и журнал регистрации;
- ⏱️ параметр времени ожидания блокировки;
- 🕐 разнесение тяжёлых операций по времени — главный рабочий инструмент.
Если база растёт, а одновременно работают всё больше людей, конфликты в файловом варианте неизбежны. Решение — перевод на клиент-серверный вариант с СУБД (MS SQL или PostgreSQL).
В клиент-серверной базе блокировки точечные: по конкретным записям регистров. Здесь работают все инструменты сразу: консоль кластера, технологический журнал, мониторинг СУБД, правка индексов и разделение итогов.
| Файловая | Клиент-серверная | |
|---|---|---|
| Уровень блокировки | Таблица | Запись (при управляемом режиме) |
| Поиск виновника | Активные пользователи, журнал регистрации | Плюс консоль кластера, техжурнал, СУБД |
| Основное средство | Разнести операции по времени | Оптимизация транзакций и кода |
Как не допускать конфликтов блокировок
- 📅 Составьте расписание тяжёлых операций: закрытие месяца, перепроведение, обмены — вне рабочих часов.
- ⚙️ Раз в квартал проверяйте список регламентных заданий: отключайте ненужные, переносите тяжёлые на ночь.
- 🗄️ Настройте регулярное обслуживание СУБД ночью: обновление статистик и перестроение индексов. Со старой статистикой запросы читают лишнее и дольше держат блокировки.
- 🧑💻 Для доработок введите правило: блокировка только с полями, сразу исключительная, без диалогов и внешних вызовов внутри транзакции.
- 🧪 Новые обработки тестируйте на копии базы с несколькими параллельными сеансами, а не одним пользователем.
- 📈 Следите за нагрузкой сервера: нехватка памяти и медленный диск растягивают транзакции.
Перед изменением конфигурации, режима блокировок или параметров базы сделайте резервную копию и проверьте изменения на тестовой копии.
Частые ошибки при борьбе с конфликтами
- ❌ Поднять таймаут до нескольких минут и забыть. Ошибки исчезнут, но пользователи будут висеть на проведении по минуте, а взаимоблокировки останутся.
- ❌ Перезапускать сервер 1С при каждом конфликте. Это обрывает все сеансы, а причина вернётся при следующем запуске той же обработки.
- ❌ Считать, что база испорчена, и запускать тестирование и исправление. Конфликт блокировок не повреждает данные. Тестирование и исправление требует монопольного доступа и только остановит работу всех.
- ❌ Чинить не тот механизм. Ошибка «объект редактируется другим пользователем» — это блокировка формы, к транзакциям она не относится. Таймаут и разделение итогов её не лечат.
- ❌ Перевести самописную конфигурацию в управляемый режим одной галочкой. Без явных блокировок в коде проведения появится риск продать один остаток дважды.