В процессе эксплуатации распределенных информационных баз (РИБ) технические специалисты часто сталкиваются с ситуацией, когда обмен данными в центральном узле проходит без нареканий, но в подчиненных узлах возникает критическая ошибка. Одной из самых коварных является ошибка: «Ошибка чтения файла сообщения обмена... База данных заблокирована». Примечательно, что блокировщиком выступает тот же самый сеанс, который и инициировал синхронизацию. Рассмотрим детально причины этого явления и способы его устранения.
Типичная ситуация разворачивается на платформе 8.3.13.1690 (или близких версиях) и конфигурации Розница 2.2. При попытке синхронизации в периферийном узле система выдает ошибку в модуле Обработка.КонвертацияОбъектовРаспределенныхИнформационныхБаз.МодульОбъекта при вызове метода ПрочитатьИзменения.
Проанализируем ключевой момент: ошибка сообщает, что база заблокирована пользователем, под которым запущен текущий обмен. Это классический случай «блокировки самого себя», который часто ставит в тупик даже опытных администраторов. При этом стандартные процедуры, такие как очистка кэша, тестирование и исправление (ТиИ) или перезагрузка сервера, не приносят долгосрочного результата.
Разберем, как именно запускается процесс синхронизации. В современных версиях 1С:Розница нажатие кнопки «Синхронизировать» инициирует выполнение процесса в фоне. Проанализируем программный код, который задействуется в этот момент:
Посмотрим на разницу в методах запуска:
ОбщийМодуль.ОбменДаннымиСервер.ВыполнитьОбменДаннымиДляУзлаИнформационнойБазы.ОбщийМодуль.ДлительныеОперации.ВыполнитьВФоне.Выясним, к чему это приводит: при запуске фонового задания платформа создает отдельный сеанс. Если в системе установлены расширения конфигурации, то при старте этого фонового сеанса происходит проверка и обновление кэша расширений. Это может наложить эксклюзивную блокировку на всю базу данных, препятствуя выполнению метода ПрочитатьИзменения в основном потоке обмена.
Наиболее вероятной причиной в версиях платформы 8.3.13 является официально признанный баг платформы под номером 30167210. Проанализируем механизм его работы: когда в информационной базе присутствуют расширения, затрагивающие объекты, участвующие в обмене, платформа некорректно обрабатывает блокировки метаданных.
Это происходит потому, что при загрузке данных РИБ платформа пытается сопоставить изменения в файле обмена с текущей структурой метаданных, включая те, что привносятся расширениями. В этот момент возникает конфликт прав доступа к таблицам базы данных на уровне СУБД (или файла 1CD в случае файловой версии).
Рассмотрим еще один важный аспект — миграцию данных регистра сведений СоставыГруппыПользователей. Если пользователь, под которым выполняется синхронизация, входит в группу, состав которой изменился в центральной базе, то при загрузке сообщения обмена в периферийный узел система пытается обновить права доступа «на лету» для текущего активного сеанса.
Посмотрим на пример логики, которая может вызывать конфликт:
// В момент загрузки изменений через ПрочитатьИзменения()
// Система обнаруживает изменения в СоставыГруппыПользователей
// Пытается обновить параметры сеанса текущего пользователя
// Возникает блокировка таблицы, так как сеанс сам удерживает транзакцию обмена
Поскольку корень проблемы часто кроется в ошибке платформы, первым делом рекомендуется выполнить обновление. Баг 30167210 был исправлен в следующих версиях:
8.3.13 — начиная с версии 8.3.13.1809.8.3.14 — начиная с версии 8.3.14.1779.8.3.15 и выше.Чтобы избежать конфликтов при обновлении прав доступа, проанализируем настройки прав. Рекомендуется создать специального пользователя (например, АдминистраторОбмена), который:
СоставыГруппыПользователей (для этого можно временно отменить регистрацию изменений по данному объекту в мониторе обмена).Если обновление платформы временно невозможно, попробуем минимизировать влияние расширений:
Как мы выяснили ранее, проблема часто проявляется именно при использовании «длительных операций». Если стандартная кнопка «Синхронизировать» выдает ошибку блокировки, разберем обходной путь:
При таком подходе платформа чаще использует текущий сеанс без создания фоновых потоков, что позволяет успешно прочитать файл обмена Message_XXX_YYY.xml без возникновения ложных блокировок.
Проанализируем состояние файловой системы (для файловых баз). Иногда ошибка «База данных заблокирована» может быть вызвана «фантомными» блокировками. Для их устранения выполним следующие шаги:
*.lck, а также временные файлы *.1cl.Соблюдение этих рекомендаций позволит стабилизировать работу РИБ и избавиться от назойливых ошибок блокировки метаданных при обмене.