В процессе эксплуатации распределенных информационных баз (РИБ) в 1С:Розница, особенно в магазинах с высокой интенсивностью продажи алкоголя, часто возникает критическая проблема: блокировка таблиц при одновременном выполнении обмена и пробитии чеков. Это приводит к тому, что данные об ответе ЕГАИС не могут быть записаны в базу, работа кассира останавливается, а фоновые задания обмена «вешают» систему. Проанализируем причины этой ситуации и разберем эффективные методы борьбы с блокировками в файловом режиме.
Разберем природу проблемы. В файловом варианте работы 1С:Предприятие блокировки всегда более «грубые», чем в клиент-серверном. Основная причина конфликта заключается в следующем: при выполнении стандартного обмена через ПланыОбмена.ЗаписатьИзмененияУзла() система накладывает табличную блокировку на таблицы регистрации изменений. Если в этот момент кассир пробивает алкогольный чек, программа пытается записать данные в справочник ПрисоединенныеФайлыЕгаис и связанные регистры. Так как эти объекты часто включены в состав РИБ, попытка регистрации этих изменений натыкается на уже заблокированную таблицу регистрации изменений.
Многие разработчики пытаются решить вопрос программной отменой фонового задания обмена при возникновении ошибки блокировки. Однако, как показывает практика, вызов ФоновыеЗадания.Отменить() не освобождает таблицы мгновенно. Рассмотрим подробнее, почему это происходит и как правильно управлять процессом.
Выясним причину, по которой отмена фонового задания не помогает сразу. В файловом режиме (файл .1cd) любая транзакция должна быть либо полностью завершена (Commit), либо полностью отменена (Rollback). Если обмен длился, например, 2 минуты и успел обработать часть данных, то при его принудительной отмене платформа инициирует откат транзакции. Пока база данных возвращает состояние таблиц к исходному, блокировка сохраняется. Это время прямо пропорционально количеству данных, которые обмен успел обработать до прерывания.
Рассмотрим по шагам правильный алгоритм отмены фонового задания, который позволяет минимизировать ожидание:
Отменить().Отменено.Пример кода для реализации такой логики:
ЗаданияОбмена = ФоновыеЗадания.ПолучитьФоновыеЗадания(Новый Структура("Состояние, Метод", СостояниеФоновогоЗадания.Активно, "СтандартныеПодсистемы.ОбменДаннымиВТранзакции"));
Для Каждого Задание Из ЗаданияОбмена Цикл
Задание.Отменить();
КонецЦикла;
// Цикл ожидания фактического снятия блокировки
КонецПаузы = ТекущаяДата() + 5;
Пока ТекущаяДата() < КонецПаузы Цикл
// Проверка состояния или попытка записи в попытке-исключении
КонецЦикла;
Проанализируем альтернативный технический подход. Вместо стандартного метода ЗаписатьИзмененияУзла, который блокирует таблицы на весь период формирования XML-файла, можно использовать итерационный метод ПланыОбмена.ВыбратьИзменения().
Рассмотрим, что это дает: мы можем выбирать объекты порциями и сериализовать их самостоятельно. Это позволяет разделять процесс на множество коротких транзакций. Между этими транзакциями система будет иметь «окна», в которые сможет вклиниться кассовая операция пробития чека. Это более трудоемкий путь, так как он требует частичного переписывания механизмов обмена, но он практически полностью исключает длительные блокировки.
Часто проблема кроется в избыточности данных. Проанализируем ситуацию: действительно ли нам нужно передавать тяжелые двоичные данные из справочника ПрисоединенныеФайлыЕгаис каждые 15 минут? Эти данные обычно нужны в центральном офисе для архива или сверки, но не для оперативной работы магазина.
Рекомендуемые действия по оптимизации:
1С:Розница 2.3 используйте встроенную возможность отложенной отправки данных в ЕГАИС, что позволит разнести во времени момент печати чека для покупателя и момент записи данных в базу.Не забудем про системные настройки, которые влияют на стабильность работы в файловом режиме:
Во-первых, проверьте Период ожидания блокировки данных. Для кассового узла это значение в конфигурации или настройках пользователя стоит увеличить до 20-30 секунд. Это позволит кассовой операции «подождать», пока обмен завершит короткий этап записи, вместо того чтобы сразу выдавать ошибку.
Во-вторых, обратите внимание на фрагментацию файла .1cd. При частом обмене (раз в 15 минут) таблица регистрации изменений постоянно растет и очищается. Это приводит к раздуванию файла базы данных. Регулярно (раз в неделю) выполняйте процедуру «Сжатие таблиц» в утилите chdbfl.exe или через Тестирование и Исправление.
Если программные методы не помогают, стоит рассмотреть изменение архитектуры:
PostgreSQL или MS SQL Express на кассовом сервере магазина решит проблему за счет полноценных управляемых блокировок на уровне записей, а не таблиц.Подводя итог, скажем: блокировки при обмене в РИБ — это следствие попытки выполнить две тяжелые операции записи в одну таблицу в файловом режиме. Сочетание превентивной остановки заданий, оптимизации состава передаваемых данных и перехода на итерационную выгрузку позволяет добиться стабильной работы кассы даже при интенсивном обмене данными.