Взаимоблокировки (deadlocks) в конфигурации "Управление производственным предприятием" (УПП) — это классическая проблема, с которой сталкиваются многие компании при росте количества одновременно работающих пользователей. Ситуация осложняется тем, что УПП традиционно работает в режиме совместимости с платформой 8.2.13, что накладывает определенные ограничения на механизмы управления блокировками. Разберем подробно, почему возникают эти ошибки и как их можно устранить, не прибегая к немедленному переходу на ERP.
Прежде всего, проанализируем техническую подоплеку. В режиме совместимости 8.2.13 по умолчанию используются автоматические блокировки. Это означает, что управлением очередностью доступа к данным занимается непосредственно СУБД (Microsoft SQL Server). При проведении документа система устанавливает блокировки на уровне таблиц или страниц данных в зависимости от того, какие регистры затрагиваются. Рассмотрим основные факторы, провоцирующие конфликты:
Lock Escalation, что моментально парализует работу всех остальных пользователей.Как показывает практика и опыт участников обсуждения, зачастую проблема решается не изменением кода, а корректным администрированием базы данных. Если статистика устарела, оптимизатор SQL Server может выбрать неэффективный план запроса, который будет удерживать блокировки дольше необходимого. Реализуем следующий план обслуживания:
Одним из наиболее эффективных методов борьбы с блокировками "чтение против записи" является перевод базы данных в режим Read Committed Snapshot Isolation. Это позволяет читающим транзакциям получать версию данных из tempdb, не ожидая завершения пишущих транзакций.
Выясним, как это сделать. Для включения данного режима необходимо выполнить SQL-скрипт (предварительно убедившись, что к базе нет активных подключений):
ALTER DATABASE [Имя_Вашей_Базы] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE [Имя_Вашей_Базы] SET READ_COMMITTED_SNAPSHOT ON;
ALTER DATABASE [Имя_Вашей_Базы] SET ALLOW_SNAPSHOT_ISOLATION ON;
ALTER DATABASE [Имя_Вашей_Базы] SET MULTI_USER;
Важно: При включении этого режима нагрузка на базу tempdb возрастает, поэтому убедитесь, что она расположена на быстрых SSD-дисках и разделена на несколько файлов данных (по количеству ядер процессора).
Посмотрим на настройки самого сервера. Для систем 1С критически важным является параметр Max Degree of Parallelism (MAXDOP). Рассмотрим рекомендации:
MAXDOP в значение 1. Это предотвратит ситуацию, когда один тяжелый запрос захватывает все ресурсы процессора и порождает ожидания типа CXPACKET.Cost Threshold for Parallelism рекомендуется поднять до 50.В настройках кластера 1С проанализируем параметр "Количество соединений на процесс". В условиях УПП и большого количества блокировок эффективно работает стратегия разделения нагрузки. Если у вас 40-50 пользователей, попробуйте ограничить количество соединений на один рабочий процесс rphost (например, до 20). Это позволит создать несколько процессов, что повысит общую отказоустойчивость системы при зависании отдельных транзакций.
Если административные меры не помогают, придется рассмотреть архитектурные изменения. Рассмотрим два пути:
Управляемый, после чего программист должен вручную прописать блокировки в коде перед выполнением запросов к базе данных. Разберем пример установки блокировки в коде:
ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиТоваров");
ЭлементБлокировки.УстановитьЗначение("Склад", СкладОбъект);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();
Это позволит системе блокировать только те данные, которые действительно нужны документу, не затрагивая записи других менеджеров или складов.
Чтобы понять, какой именно документ или отчет вызывает проблему, воспользуемся инструментами диагностики. Проанализируем ситуацию с помощью Технологического журнала (ТЖ). Настроим сбор событий TLOCK и TDEADLOCK. Это поможет нам увидеть строки кода 1С, на которых происходит ожидание.
Параллельно используем SQL Server Profiler или Extended Events. Нас интересуют события Deadlock graph и Lock:Timeout. Граф взаимоблокировки наглядно покажет два процесса, которые пытаются захватить ресурсы друг друга, и укажет на конкретные таблицы и индексы.
Резюме: Для быстрого решения проблемы в УПП начните с регламентных операций в SQL (статистика и индексы) и включения RCSI. Если это не поможет, проанализируйте настройки MAXDOP и распределение процессов в кластере. Полный отказ от блокировок возможен только при переходе на управляемый режим, что является серьезным инвестиционным проектом по переработке кода конфигурации.