Переход с распределенных информационных баз (РИБ) в единую централизованную базу — это логичный шаг в развитии ИТ-архитектуры предприятия, стремящегося к консолидации данных в реальном времени. Однако в старых конфигурациях на обычных формах, таких как Управление торговым предприятием (УТП), этот процесс часто натыкается на серьезную техническую преграду: конфликты блокировок при одновременной работе множества пользователей. Особенно остро эта проблема проявляется при оформлении документов Чек ККМ кассирами в разных торговых точках.
В рамках данной статьи мы подробно разберем, как оптимизировать работу системы, чтобы кассиры из разных магазинов не блокировали друг друга, и какие настройки необходимо изменить в конфигурации и на сервере СУБД.
Разберем ситуацию: в режиме РИБ каждый магазин работал в своей локальной базе, и транзакции проведения чеков были изолированы друг от друга физически. При объединении всех пользователей в одну базу данные начинают записываться в одни и те же таблицы регистров. Если в конфигурации установлен автоматический режим блокировок, СУБД (например, MS SQL Server) для обеспечения целостности транзакции накладывает блокировки на уровне таблиц или больших диапазонов индексов.
Проанализируем типичное поведение системы в автоматическом режиме: когда один кассир на Складе №1 проводит чек, СУБД может заблокировать таблицу остатков целиком. В этот момент кассир на Складе №2 не может завершить свою продажу и получает сообщение об ошибке или длительное ожидание. Это происходит даже при условии, что склады у них разные и данные фактически не пересекаются.
Первое, что нам необходимо сделать, — это пересмотреть политику блокировок в конфигурации. Как отмечается в обсуждении, часто встречается «смешанный режим», когда сама конфигурация находится в режиме Управляемый, а конкретные объекты (документы и регистры) — в режиме Автоматический.
Рассмотрим порядок действий для изменения режима:
ТоварыНаСкладах или ПартииТоваровНаСкладах).Режим управления блокировкой данных с Автоматический на Управляемый.Чек ККМ.Важно понимать: простое переключение свойства не решит проблему. В управляемом режиме 1С снимает ответственность с СУБД и перекладывает ее на разработчика. Теперь мы сами должны в коде указать системе, какие именно данные мы хотим заблокировать перед записью.
Для того чтобы пользователи не мешали друг другу, мы применим стратегию «гранулярных блокировок». Поскольку в УТП кассиры работают каждый со своим складом, мы будем блокировать данные только в разрезе конкретного склада и, при необходимости, номенклатуры.
Выясним, как это реализовать в коде. В модуле проведения документа (или в обработке заполнения наборов записей регистров) необходимо создать объект БлокировкаДанных. Разберем пример реализации:
// Создаем новый объект блокировки
ЭлементБлокировки = БлокировкаДанных.Добавить();
// Указываем пространство блокировки (конкретный регистр)
ЭлементБлокировки.Область = "РегистрНакопления.ТоварыНаСкладах";
// Устанавливаем режим: Исключительный (для записи данных)
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
// Устанавливаем фильтр по складу, чтобы не блокировать продажи других магазинов
ЭлементБлокировки.УстановитьЗначение("Склад", СкладДляПродажи);
// Если нужно заблокировать конкретные товары из табличной части
ЭлементБлокировки.ИсточникДанных = Товары;
ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура", "Номенклатура");
// Активируем блокировку
БлокировкаДанных.Заблокировать();
С помощью этого механизма мы добьемся того, что транзакция кассира со Склада №1 никак не затронет транзакцию кассира со Склада №2. Они будут «ждать» друг друга только в том случае, если оба попытаются одновременно продать товар с одного и того же склада.
Даже при внедрении управляемых блокировок остаются «узкие места», характерные для архитектуры УТП на обычных формах. Рассмотрим подробнее два из них: последовательности документов и таблицы итогов.
Разберем проблему последовательностей: Если в документе Чек ККМ включено автоматическое движение границы последовательности (например, партионного учета), система будет пытаться заблокировать таблицу Последовательности. Это общее место для всех складов. При интенсивной работе десятков кассиров это гарантированно вызовет очередь. Рекомендуем отключить автоматическое восстановление последовательностей при проведении чеков, перенеся эту задачу на регламентное задание в ночное время.
Проанализируем работу с итогами: Для регистров остатков крайне важно включить свойство Разделение итогов. Посмотрим, что это дает: 1С будет записывать приращения итогов в разные «слоты» (строки) физической таблицы итогов СУБД. Это позволяет нескольким пользователям одновременно записывать движения в один и тот же регистр без возникновения конфликтов на уровне СУБД.
Перевод базы в управляемый режим блокировок меняет поведение MS SQL Server. В этом режиме 1С переключает уровень изоляции транзакций на Read Committed Snapshot Isolation (RCSI). Это позволяет пользователям читать данные (например, строить отчеты по остаткам), не блокируя при этом запись новых документов, и наоборот.
Обратим внимание на аппаратную часть:
LDF) становится обязательным условием.tempdb в соответствии с количеством ядер процессора. Это снизит нагрузку при формировании сложных временных таблиц в запросах проведения._AccumReg и _Document в кэше.Подводя итог, можно утверждать, что работа в единой базе после РИБ вполне возможна без потери производительности, если подойти к вопросу системно. Выясним краткий алгоритм внедрения изменений:
Управляемый для всех новых объектов.Управляемый.Чек ККМ программную установку объекта БлокировкаДанных с обязательной фильтрацией по складу.Разделение итогов для всех регистров накопления.Такой комплексный подход позволит вашей системе стабильно работать с большим количеством пользователей, обеспечивая при этом высокую скорость обслуживания покупателей на кассовых узлах.