Как предотвратить блокировки в 1С:Розница при фоновой синхронизации и предупредить кассира?

Программист 1С v8.3 (Управляемые формы) 1С:Розница Управленческий учет Торговля и дистрибуция
← На главную

При совместной работе распределенных информационных баз (РИБ) в связке «1С:Управление торговлей — 1С:Розница» администраторы и программисты часто сталкиваются с критической проблемой. В момент проведения фонового автообмена кассир на торговой точке пытается пробить чек. Из-за пересечения транзакций база данных блокирует таблицы. В результате на фискальном регистраторе чек успешно печатается, а в программе «1С» транзакция откатывается из-за ошибки совместного доступа. Чек остается в статусе «Не провелся», выручка в программе не отражается, а товар не списывается.

В этой статье мы подробно разберем, как решить проблему взаимных блокировок при синхронизации, как настроить время ожидания блокировок СУБД, а также как реализовать программный механизм оповещения кассира в рабочем месте кассира (РМК).

Выясняем причину: почему возникают блокировки?

В процессе обмена данными система «1С:Предприятие» производит запись большого объема объектов (документов, справочников, регистров сведений). При записи любого объекта СУБД накладывает исключительную блокировку на таблицы базы данных, чтобы гарантировать целостность транзакции. Если в этот же момент кассир проводит чек, программе требуется обновить таблицы остатков товаров и взаиморасчетов, которые уже заблокированы процессом обмена.

По умолчанию в платформе «1С:Предприятие» время ожидания блокировки данных составляет 20 секунд. Если транзакция загрузки пакета обмена длится дольше (например, 40 секунд), то по истечении 20 секунд касса «вылетает» с ошибкой СУБД, хотя команда на фискальный аппарат уже могла уйти.

Решение 1. Увеличение времени ожидания блокировки данных

Самый быстрый административный способ решить проблему — дать кассовой транзакции больше времени «дождаться» окончания записи пакета обмена. Рассмотрим, как это сделать по шагам:

  1. Анализ статистики: Прежде чем менять параметры, проанализируем среднее время фонового обмена. Сделать это можно в журнале регистрации или через обработку «Регистрация изменений для обмена данными». Выясним, сколько секунд обычно занимает загрузка и проведение одного пакета. Если среднее время загрузки составляет 40–50 секунд, время ожидания блокировки имеет смысл увеличить.
  2. Изменение параметров базы данных: Нам необходимо установить время ожидания блокировки, превышающее среднее время записи пакета обмена. Рекомендуемое безопасное значение — 120 секунд (2 минуты).
  3. Где это настраивается:
    • В файловом варианте работы базы данных этот параметр можно изменить в свойствах конфигурации.
    • В клиент-серверном варианте (SQL) настройка выполняется через консоль администрирования серверов «1С:Предприятия». Откроем свойства нашей информационной базы и в поле «Время ожидания блокировки данных» установим значение 120.

Если мы установим 120 секунд (или даже 5 минут), то при начале обмена чек у кассира не выдаст ошибку сразу. Программа просто «задумается» на время записи пакета обмена, а как только транзакция синхронизации завершится, чек успешно проведется без сбоев.

Решение 2. Программный механизм блокировки РМК («семафор»)

Чтобы кассир не испытывал дискомфорта от «зависания» интерфейса во время оплаты, мы можем реализовать механизм программных флагов-семафоров. Рассмотрим алгоритм его работы:

Создадим простой регистр сведений или будем использовать константу, например, ИдетОбменДанными со значением типа Булево. Перед началом загрузки пакета РИБ регламентное задание устанавливает этот флаг в значение Истина, а после завершения — в Ложь.

В модуле формы РМК перед началом выполнения транзакции пробития чека добавим проверку этого флага:


// Функция проверки активности фонового обмена данными
Функция ПроверитьАктивностьОбмена() Экспорт
    Возврат Константы.ИдетОбменДанными.Получить();
КонецФункции

// Обработчик события перед пробитием чека в РМК
&НаКлиенте
Процедура ПередПробитиемЧека(Отказ)
    Если ПроверитьАктивностьОбмена() Тогда
        Отказ = Истина;
        ПоказатьПредупреждение(, "В данный момент идет фоновая синхронизация баз данных. Пожалуйста, подождите 1 минуту.", 10, "Синхронизация");
        Возврат;
    КонецЕсли;
КонецПроцедуры

Такой подход полностью исключает физическую возможность одновременного запуска двух конфликтующих транзакций.

Решение 3. Проверка статуса фонового задания на клиенте

Если мы не хотим создавать дополнительные константы, мы можем программно опрашивать состояние регламентных заданий обмена напрямую из клиента 1С с помощью обработчика ожидания.

Разберем пример подключения такого обработчика в форме РМК:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подключаем опрос состояния обмена каждые 15 секунд
    ПодключитьОбработчикОжидания("ПроверитьСтатусСинхронизации", 15, Ложь);
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьСтатусСинхронизации()
    ВыполняетсяОбмен = ВыяснитьСтатусФоновогоОбменаНаСервере();
    
    Если ВыполняетсяОбмен Тогда
        // Делаем кнопку пробития чека недоступной и выводим баннер-предупреждение
        Элементы.КнопкаПробитьЧек.Доступность = Ложь;
        Элементы.ДекорацияПредупреждениеОбмен.Заголовок = "Внимание: идет фоновый обмен данными!";
        Элементы.ДекорацияПредупреждениеОбмен.Видимость = Истина;
    Иначе
        Элементы.КнопкаПробитьЧек.Доступность = Истина;
        Элементы.ДекорацияПредупреждениеОбмен.Видимость = Ложь;
    КонецЕсли;
КонецПроцедуры

На сервере код проверки запущенных фоновых заданий обмена будет выглядеть следующим образом:


&НаСервереБезКонтекста
Функция ВыяснитьСтатусФоновогоОбменаНаСервере()
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("Состояние", СостояниеФоновогоЗадания.Активно);
    
    // Ищем активные задания по имени нашего регламентного задания обмена
    СписокЗаданий = ФоновыеЗадания.ПолучитьФоновыеЗадания(ПараметрыОтбора);
    Для Каждого Задание Из СписокЗаданий Цикл
        Если Найти(Задание.Наименование, "Выполнить обмен данными") > 0 Тогда
            Возврат Истина;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Ложь;
КонецФункции

Решение 4. Оптимизация параметров самого обмена РИБ

Зачастую блокировки возникают из-за неоптимальных настроек записи данных в правилах обмена. Проанализируем настройки узла распределенной информационной базы:

Решение 5. Изменение архитектуры и расписания обменов

Зададимся вопросом: действительно ли необходим обмен каждые 30 минут? В розничной торговле оперативные остатки в бэк-офисе (УТ) часто требуются для перемещения товаров между точками.

Если это так, рассмотри альтернативные варианты интеграции:

Что делать, если чек уже завис (пробит на кассе, но не проведен в 1С)?

Если блокировка все же произошла, и чек завис, научим персонал торговой точки действовать по строгому регламенту:

  1. Не нажимать кнопку повторно! Повторное нажатие приведет к повторной отправке команды на ККТ, в результате чего кассовый аппарат выдаст второй физический чек, выручка в ОФД задвоится, а с карты покупателя повторно спишутся средства.
  2. Ручное проведение чека: Администратору необходимо открыть стандартный журнал «Чеки ККМ», найти непроведенный чек, открыть его, вручную заполнить реквизиты фискального документа (номер смены и номер чека с напечатанного бумажного чека) и просто провести документ стандартной кнопкой «Провести» (без нажатия кнопки «Пробить»). Это корректно спишет товар со склада в программе без повторного обращения к кассовому аппарату.
← На главную