Как исправить ошибку совместного доступа к файлу при интеграции 1С и Битрикс

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

При настройке стандартного обмена между 1С:Предприятие и сайтом на базе 1С-Битрикс специалисты часто сталкиваются с неприятной ошибкой: Ошибка при вызове конструктора (ЧтениеТекста). В тексте ошибки указывается причина: Ошибка совместного доступа к файлу, и путь к временному файлу в каталоге tmp. Эта проблема особенно актуальна для высоконагруженных систем и серверов, работающих под управлением Linux (Debian, Ubuntu), хотя встречается и на Windows.

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

Разбор причины: почему возникает конфликт доступа?

Проанализируем ситуацию. Обмен данными — это итерационный процесс. 1С формирует пакет данных (XML), упаковывает его в ZIP и отправляет на сайт. Сайт обрабатывает пакет и возвращает ответ. Ошибка Ошибка совместного доступа к файлу означает, что один процесс (например, поток записи лога или основной процесс rphost) еще удерживает файл, в то время как другой процесс пытается его прочитать или перезаписать.

Выделим основные факторы, провоцирующие проблему:

  1. Параллельные сессии обмена: Если узел обмена запущен регламентным заданием и одновременно пользователь запускает его вручную, возникает «состояние гонки» (race condition).
  2. Детальное логирование: При включенной опции «Вести детальный лог» модуль Б_ОбменССайтомСервер обращается к текстовому файлу практически на каждом шаге. Если запись в файл не успела завершиться на уровне ОС, следующая попытка обращения вызывает блокировку.
  3. Задержки файловой системы: На ОС Linux временные файлы могут удерживаться дескрипторами процессов чуть дольше, чем этого ожидает платформа 1С.

Решение 1: Модификация кода логирования (самый эффективный метод)

Рассмотрим наиболее действенное решение, предложенное опытными разработчиками. Суть заключается в том, чтобы при возникновении ошибки доступа к файлу лога не останавливать весь обмен, а просто изменить имя файла лога и продолжить работу. Нам необходимо внести изменения в процедуру СообщитьПодробно модуля Б_ОбменССайтомСервер.

Разберем по шагам, как модифицировать код:


Попытка
    // Пытаемся открыть файл лога для дозаписи
    Текст = Новый ЗаписьТекста(ОсновныеПараметры.ИмяФайлаЛога, КодировкаТекста.ANSI, , Истина);
    Текст.ЗаписатьСтроку(Строка(ТекущаяДата()) + " -- " + пСобытие);
    Текст.Закрыть();
Исключение
    // Если файл заблокирован, фиксируем ошибку в Журнале регистрации 1С
    ЗаписьЖурналаРегистрации("СобытияОбменаДанныхМодуляБитрикс", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки() + " " + пСобытие);
    
    // Генерируем новое уникальное имя файла, чтобы избежать конфликта
    ОсновныеПараметры.ИмяФайлаЛога = СтрЗаменить(ОсновныеПараметры.ИмяФайлаЛога, ".txt", "_.txt");
    
    // Пробуем записать лог в новый файл
    Попытка
        Текст = Новый ЗаписьТекста(ОсновныеПараметры.ИмяФайлаЛога, КодировкаТекста.ANSI, , Истина);
        Текст.ЗаписатьСтроку(Строка(ТекущаяДата()) + " -- " + пСобытие);
        Текст.Закрыть();
    Исключение
        // Если и здесь неудача, просто игнорируем, чтобы не прерывать основной обмен
    КонецПопытки;
КонецПопытки;

Этот подход позволяет обойти блокировку, создавая «цепочку» логов (например, log.txt, log_.txt, log__.txt), и гарантирует, что основной процесс загрузки товаров или заказов не прервется из-за второстепенной функции записи отладочной информации.

Решение 2: Внедрение механизма повторных попыток чтения (Retry Loop)

Если ошибка возникает при чтении файла ответа от сервера (ИмяФайлаОтвета), это часто связано с тем, что HTTP-соединение закрыто, но ОС еще не освободила временный файл. В этом случае мы рекомендуем внедрить цикл ожидания в процедуру ПолучитьОтветСервера.

Проанализируем пример реализации:


// Вместо прямого вызова: ЧтениеТекста = Новый ЧтениеТекста(ИмяФайлаОтвета, лКодировка);
// Используем цикл с паузой

МаксПопыток = 5;
Для Итерация = 1 По МаксПопыток Цикл
    Попытка
        ЧтениеТекста = Новый ЧтениеТекста(ИмяФайлаОтвета, лКодировка);
        Прервать; // Успешное чтение, выходим из цикла
    Исключение
        Если Итерация = МаксПопыток Тогда
            // Если все попытки исчерпаны, пробрасываем исключение выше
            ВызватьИсключение "Не удалось прочитать файл ответа от сайта после 5 попыток. " + ОписаниеОшибки();
        КонецЕсли;
        
        // Небольшая пауза (около 1 секунды) перед следующей попыткой
        // В 1С паузу можно реализовать через Предупреждение (но не на сервере!) 
        // или через фоновое задание/команду ОС.
        // Простейший вариант для сервера:
        ТекущееВремя = ТекущаяДата();
        Пока ТекущаяДата() < ТекущееВремя + 1 Цикл
            // Пустой цикл ожидания 1 секунду
        КонецЦикла;
    КонецПопытки;
КонецЦикла;

Такой подход дает операционной системе время завершить все операции ввода-вывода и снять блокировку с дескриптора файла.

Решение 3: Настройка параметров обмена и окружения

Посмотрим на проблему шире. Иногда изменения кода можно избежать, если правильно настроить окружение и параметры самого модуля Битрикс в 1С.

  1. Отключение детального логирования: Перейдем в настройки узла обмена и снимем галочку «Вести детальный лог». В большинстве случаев это полностью устраняет ошибку совместного доступа, так как количество обращений к файловой системе сокращается в десятки раз.
  2. Очистка временных папок: На серверах Linux (Debian) убедимся, что у пользователя usr1cv8 есть полные права (777 или rwx) на папку /home/usr1cv8/tmp. Также рекомендуется периодически очищать эту папку от старых файлов *.tmp, так как их накопление (десятки тысяч файлов) замедляет работу файловой системы.
  3. Проверка прав через umask: Проанализируем настройки umask для пользователя, под которым запущен сервер 1С. Рекомендуется установить umask 0002, чтобы создаваемые файлы были доступны для записи группе.
  4. Антивирусное ПО: Если на сервере установлен антивирус, добавим папку с временными файлами 1С и папку с логами обмена в исключения (белый список). Антивирусы часто блокируют файлы для сканирования именно в момент их закрытия, что вызывает конфликты в 1С.

Решение 4: Использование альтернативных методов обмена

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

Преимущества этого метода:

Подведем итог. Ошибка совместного доступа — это чаще всего вопрос таймингов и избыточного логирования. Начнем с отключения детального лога, и если это не поможет, перейдем к модификации кода модуля Б_ОбменССайтомСервер с использованием блоков Попытка...Исключение и уникальных имен файлов. Эти меры позволят сделать ваш обмен с Битриксом стабильным и отказоустойчивым.

← На главную