При проектировании интеграции между 1С и внешними информационными системами (например, фронт-офисом, сайтом или сторонними СУБД) разработчики часто сталкиваются с дилеммой. С одной стороны, механизм Внешних источников данных (ВИД) в 1С манит своей простотой: подключился напрямую к SQL-таблице и читай/пиши данные. С другой стороны, опытные архитекторы называют такой подход устаревшим и опасным.
В этой статье мы подробно разберем, почему прямой обмен через общие таблицы SQL (паттерн Shared Database) часто превращается в головную боль, какие скрытые риски несет механизм ВИД и как спроектировать надежный, современный обмен с использованием брокеров сообщений и интеграционных шин.
---
Давайте проанализируем классический сценарий. Внешняя система (например, сайт или кассовый модуль) записывает данные в специальную "буферную" таблицу в СУБД MS SQL или PostgreSQL. Платформа 1С по расписанию опрашивает эту таблицу, забирает новые записи, обрабатывает их и помечает как обработанные. Данная схема кажется простой, но на практике мы сталкиваемся со следующими критическими проблемами:
Ниже представлен типичный пример неэффективного кода, который часто пишут разработчики для опроса внешней таблицы:
// Пример неэффективного опроса таблицы через ВИД
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВнешняяТаблица.Идентификатор КАК ID,
| ВнешняяТаблица.ДанныеЗаказа КАК Данные
|ИЗ
| ВнешнийИсточникДанных.ВнешняяБД.Таблица.ОчередьОбмена КАК ВнешняяТаблица
|ГДЕ
| ВнешняяТаблица.СтатусОбработки = ""Новый""";
РезультатЗапроса = Запрос.Выполнить();
// Далее следует перебор выборки и запись в 1С, что блокирует таблицу в SQL
---
Помимо общих архитектурных недостатков, сам встроенный механизм ВИД в платформе 1С имеет ряд технических ограничений, о которых нужно помнить:
JOIN) таблицы из разных внешних источников данных внутри одного запроса. Также сильно ограничена работа с временными таблицами.1С:ERP или 1С:Комплексная автоматизация).---
Существует заблуждение: "Если мы записали данные в таблицу SQL, значит, они доставлены. Подтверждение получения не требуется". Это в корне неверно.
Гарантированная доставка — это не просто успешная фиксация транзакции записи во временную таблицу. Настоящая гарантированная доставка подразумевает, что принимающая сторона (в данном случае 1С) не просто "увидела" строку, но и успешно ее распарсила, провела по всем правилам бизнес-логики (например, создала проведенный документ РеализацияТоваровУслуг) и отправила отправителю статус: "Данные успешно применены, исходную запись можно удалить/архивировать". Если же в процессе проведения документа в 1С возникла ошибка (например, не хватило остатка товара на складе), транзакция на стороне SQL должна остаться в исходном состоянии, либо отправителю должно уйти сообщение об ошибке.
---
Для построения надежного обмена информацией вместо прямых SQL-запросов следует использовать событийно-ориентированную интеграцию (EDA) с помощью брокеров сообщений, таких как RabbitMQ.
RabbitMQ — это бесплатное программное обеспечение с открытым исходным кодом, которое выступает интеллектуальным посредником между системами. Вместо записи в SQL-таблицу внешняя система отправляет сообщение (например, JSON-пакет) в очередь брокера. 1С считывает сообщения из очереди по мере своей готовности.
Преимущества использования RabbitMQ:
SELECT-запросов.Рассмотрим концептуальный пример того, как просто отправить сообщение в очередь RabbitMQ из 1С, используя стандартный REST API брокера:
// Пример отправки сообщения в очередь RabbitMQ через HTTP REST API
НТТРСоединение = HTTPСоединение("localhost", 15672, "guest", "guest");
НТТРЗапрос = Новый HTTPЗапрос("/api/exchanges/%2f/amq.default/publish");
НТТРЗапрос.Заголовки.Вставить("Content-Type", "application/json");
// Формируем JSON-пакет с полезной нагрузкой
ТелоЗапроса =
"{
| ""properties"": {},
| ""routing_key"": ""orders_queue"",
| ""payload"": ""{\""OrderID\"": 1024, \""Total\"": 5400.00}"",
| ""payload_encoding"": ""string""
|}";
НТТРЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);
НТТПОтвет = НТТРСоединение.ОтправитьДляАнализа(НТТРЗапрос);
Если НТТПОтвет.КодСостояния = 200 Тогда
ЗаписатьЛогСобытий("Данные успешно отправлены в брокер сообщений.");
КонецЕсли;
---
Если проект масштабный, включает десятки баз данных и требует сложной маршрутизации, отличным решением станет использование готовых интеграционных шин (Enterprise Service Bus — ESB).
---
Было бы несправедливо сказать, что прямой обмен через СУБД или ВИД — это абсолютное зло в любой ситуации. Данный подход жизнеспособен, если выполняются следующие условия:
Подводя итог, ответим на вопрос автора темы: обмен 1С с SQL через внешние источники для серьезных распределенных систем — это действительно не лучшее решение, несущее в себе риски снижения производительности СУБД и усложнения поддержки кода.
Для построения надежной ИТ-архитектуры рекомендуем придерживаться следующего правила: если вы интегрируете критически важные бизнес-процессы (заказы, остатки, цены), используйте брокеры сообщений (RabbitMQ) или специализированные шины данных (1С:Шина). Оставьте механизм ВИД исключительно для локальных, простых задач интеграции со специализированным оборудованием.