Как устранить задержку при чтении данных из внешних источников SQL в 1С?

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

При интеграции 1С с внешними базами данных через механизм Внешние источники данных (ВИД) разработчики часто сталкиваются с необъяснимой задержкой. Ситуация выглядит следующим образом: одна база (например, узел РИБ) записывает данные в таблицу MS SQL, но другая база видит эти изменения не сразу, а лишь спустя 5–10 секунд. При этом, если проверить таблицу напрямую через SQL Server Management Studio (SSMS), данные появляются там мгновенно.

В этой статье мы подробно разберем, почему возникает этот эффект «протухшего кэша», и рассмотрим несколько способов обеспечения оперативного получения данных в реальном времени.

Причина задержки: внутреннее кэширование платформы 1С

Прежде чем переходить к коду, давайте проанализируем ситуацию. Платформа 1С спроектирована таким образом, чтобы минимизировать нагрузку на сеть и сервер базы данных. Когда выполняется запрос к ВнешнемуИсточникуДанных, 1С считывает данные и помещает их в локальный кэш сеанса. При повторном обращении к той же таблице в течение короткого промежутка времени платформа может вернуть данные из кэша, не обращаясь к реальному SQL-серверу.

Именно поэтому в консоли SQL Management Studio мы видим актуальную картину (она работает напрямую), а в коде 1С — старую. Платформа «не знает», что внешняя таблица была изменена другим сеансом или сторонним приложением.

Решение 1: Использование явных транзакций для сброса кэша

Наиболее простым и эффективным программным методом решения проблемы является использование транзакций 1С. Рассмотрим, как это работает. При вызове метода НачатьТранзакцию() для внешнего источника, платформа переходит в режим гарантированной согласованности данных. Чтобы обеспечить эту согласованность внутри транзакции, 1С принудительно сбрасывает локальный кэш и выполняет чтение непосредственно из SQL-сервера.

Разберем пример кода, который позволяет получить актуальные данные без задержки:


// Указываем имя нашего внешнего источника данных
ВнешнийИсточник = ВнешниеИсточникиДанных.ИмяВашегоСервераSQL;

// Открываем транзакцию, чтобы заставить 1С перечитать данные из SQL
ВнешнийИсточник.НачатьТранзакцию();

Попытка
    // Выполняем запрос или чтение таблицы
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ВнешняяТаблица.Поле1,
        |	ВнешняяТаблица.Поле2
        |ИЗ
        |	ВнешнийИсточникДанных.ИмяВашегоСервераSQL.Таблица.ИмяТаблицы КАК ВнешняяТаблица";
    
    РезультатЗапроса = Запрос.Выполнить();
    // Обработка данных...

    // Завершаем транзакцию
    ВнешнийИсточник.ЗафиксироватьТранзакцию();
Исключение
    // В случае ошибки обязательно откатываем транзакцию
    ВнешнийИсточник.ОтменитьТранзакцию();
    ЗаписьЖурналаРегистрации("Ошибка чтения SQL", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;

Важный нюанс: даже если вы только читаете данные, вызов ЗафиксироватьТранзакцию() необходим для корректного закрытия сессии обмена.

Решение 2: Настройка уровня изоляции транзакций на стороне SQL

Иногда проблема кроется в настройках самого MS SQL Server. По умолчанию в SQL используется уровень изоляции READ COMMITTED. Это означает, что читающий процесс может ожидать завершения пишущего процесса. В высоконагруженных системах это создает дополнительные задержки.

Проанализируем настройку Read Committed Snapshot Isolation (RCSI). Если включить этот режим на уровне базы данных SQL, то читающие сеансы 1С не будут блокироваться пишущими. Они будут всегда видеть последнюю зафиксированную версию данных (snapshot) на момент начала запроса.

Для включения этого режима выполните в SQL Management Studio следующий скрипт:


ALTER DATABASE [ИмяВашейБазы] SET ALLOW_SNAPSHOT_ISOLATION ON;
ALTER DATABASE [ИмяВашейБазы] SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE;

Это значительно повышает параллельность работы и помогает 1С быстрее получать подтвержденные данные из внешнего источника.

Решение 3: Управление блокировками в конфигураторе

Посмотрим на настройки метаданных. В свойствах таблицы внешнего источника данных в дереве конфигурации есть параметр «Блокировка данных».

  1. Если установлено значение «Автоматическая», 1С сама решает, когда блокировать таблицу и как кэшировать выборку. Это часто приводит к описанным задержкам.
  2. Перевод таблицы в режим «Управляемый» позволяет программисту более гибко управлять состоянием транзакций, хотя это и требует более тщательного написания кода.

Решение 4: Использование ADO для «честного» Real-time

Если специфика вашей задачи требует гарантированного отсутствия кэширования (например, мониторинг датчиков или критически важных статусов в реальном времени), рассмотрим альтернативу встроенному механизму ВИД. Это использование объекта COMОбъект("ADODB.Connection").

Этот метод работает в обход механизмов платформы 1С и обращается к драйверу SQL напрямую. Здесь кэширование 1С полностью отсутствует. Выясним, как реализовать такое подключение:


Connection = Новый COMОбъект("ADODB.Connection");
ConnectionString = "Driver={SQL Server};Server=ИмяСервера;Database=ИмяБазы;Uid=Логин;Pwd=Пароль;";

Попытка
    Connection.Open(ConnectionString);
    Command = Новый COMОбъект("ADODB.Command");
    Command.ActiveConnection = Connection;
    Command.CommandText = "SELECT Top 1 Status FROM MonitoringTable WHERE ID = 1";
    
    RecordSet = Command.Execute();
    
    Пока НЕ RecordSet.EOF Цикл
        ТекущийСтатус = RecordSet.Fields("Status").Value;
        RecordSet.MoveNext();
    КонецЦикла;
    
    Connection.Close();
Исключение
    Сообщить("Ошибка прямого доступа к SQL: " + ОписаниеОшибки());
КонецПопытки;

Метод через ADO является самым «быстрым», но он менее удобен, так как требует ручного формирования строк подключения и не позволяет использовать привычный язык запросов 1С.

Рекомендации по оптимизации ODBC

Проанализируем настройки драйвера на сервере 1С. Внешние источники данных работают через ODBC-провайдер. В настройках ODBC Data Source Administrator обратите внимание на параметры Pooling (Пул соединений).

Если пул настроен на слишком длительное удержание соединений, может возникнуть ситуация, когда сеанс 1С использует «старое» соединение с устаревшими параметрами сессии SQL. В некоторых случаях помогает принудительное переподключение источника через метод:

ВнешниеИсточникиДанных.ИмяИсточника.УстановитьОбщиеПараметрыСоединения(Параметры)

Это инициирует создание нового физического соединения с сервером, что гарантированно очищает все уровни кэширования.

Выводы

Подводя итог, если вы столкнулись с задержкой в 5–10 секунд при работе с внешним SQL в 1С, наиболее правильным путем будет:

Применяя эти методы, мы обеспечиваем высокую скорость обмена данными и исключаем ошибки, связанные с получением неактуальной информации в распределенных системах.

← На главную