При увеличении количества мобильных устройств, синхронизирующихся с центральной информационной базой 1С через веб-сервисы и планы обмена, разработчики часто сталкиваются с критической ситуацией. Когда несколько десятков или сотен устройств одновременно вызывают сервис синхронизации раз в 5–10 минут, транзакции начинают падать с ошибкой «Конфликт блокировок при выполнении транзакции». На стороне мобильного клиента при этом может возникать аварийное завершение с блокировкой таблицы config. Разберем детально природу этих блокировок и рассмотрим практические способы решения проблемы.
Проанализируем механику работы планов обмена в платформе 1С:Предприятие. При регистрации изменений для каждого узла создаются служебные записи в системных таблицах регистрации изменений. Когда мобильный узел подключается к центральной базе для чтения предназначенных ему пакетов данных, платформа обращается к этим таблицам.
Выясним причину конфликта на сервере СУБД:
Рассмотрим, откуда берется ошибка блокировки таблицы config в мобильном приложении. Локальная база мобильной платформы 1С работает под управлением встраиваемой СУБД SQLite. Архитектура SQLite устроена так, что в один момент времени писать в базу данных может только один поток.
Таблица config хранит внутреннее состояние и кэш конфигурации мобильного приложения. Ошибка означает, что база данных мобильного приложения оказалась заблокирована другим процессом либо зависла в монопольном состоянии после аварийного разрыва фонового потока. Если сетевой запрос (вызов веб-сервиса) выполняется внутри транзакции НачатьТранзакцию() на мобильном устройстве и соединение обрывается по таймауту, SQLite не успевает корректно закрыть транзакцию. Основной интерфейсный поток приложения теряет доступ к данным и аварийно завершает работу.
Разберем по шагам, как правильно разделить операции на сервере и мобильном устройстве, чтобы минимизировать время захвата блокировок.
На мобильном устройстве категорически запрещено выполнять вызовы сетевых сервисов внутри транзакций локальной базы. Посмотрим на правильный порядок реализации:
ЗафиксироватьТранзакцию()).В центральной базе процесс выгрузки изменений также необходимо разделять. Сначала в короткой транзакции фиксируются переданные мобильным клиентом данные и считываются зарегистрированные изменения в буферную переменную (или хранилище). После этого блокировка с таблиц плана обмена снимается, и сервис формирует итоговый сетевой ответ клиенту.
Рассмотрим архитектурный подход, полностью устраняющий конкуренцию мобильных клиентов за таблицу плана обмена при чтении. Вместо динамического формирования пакета в момент входящего вызова от мобильного устройства, центральная база готовит данные заранее в фоновом режиме.
Схема реализации выглядит следующим образом:
ОчередьПакетовОбмена с измерениями УзелОбмена и ресурсом типа ХранилищеЗначения для сжатого пакета данных.В этом сценарии мобильные устройства читают обычный регистр сведений по точному значению ключа записи, вообще не затрагивая системные таблицы регистрации изменений плана обмена.
Постоянный опрос базы (polling) сотней устройств раз в 5–10 минут создает колоссальный поток холостых вызовов. Если за 10 минут данных для конкретного мобильного устройства не появилось, обращение все равно создает нагрузку на веб-сервер и кратковременные блокировки.
Проанализируем правильную мобильную архитектуру на основе Push-уведомлений:
Если в конфигурации центральной базы режим управления блокировкой данных установлен в значение «Автоматический», СУБД блокирует слишком широкие диапазоны записей. Переведем конфигурацию в «Управляемый» режим. Это заставит платформу управлять блокировками на уровне логических записей 1С, исключая взаимные зависания непересекающихся узлов.
Также проанализируем структуру передаваемых данных: