Как исправить ошибку "В данной транзакции уже происходили ошибки!" при обновлении РИБ в 1С:Рознице?

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

При обновлении распределенной информационной базы (РИБ) в 1С:Рознице пользователи часто сталкиваются с ошибкой "В данной транзакции уже происходили ошибки!", особенно когда речь идет о переходе на новые релизы (например, с 2.2.6 на 2.2.12 или с 2.2.12 на 2.13.8). Эта ошибка обычно возникает в периферийном узле во время получения данных, и в журнале регистрации она часто сопровождается упоминанием документа "Ввод начальных остатков узла", а также указанием на то, что сообщение обмена удалено из кэша.

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

Подготовка к обновлению РИБ: общие рекомендации

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

  1. Создайте полные резервные копии всех узлов РИБ. Это критически важный шаг. Обязательно сохраните полные резервные копии как центральной, так и всех периферийных баз данных. В случае возникновения ошибок это позволит безболезненно вернуться к исходному состоянию.
  2. Соблюдайте последовательность обновления. Всегда начинайте обновление с центрального узла. После его успешного обновления и проверки работоспособности, переходите к периферийным узлам. Если требуется обновить базу на несколько релизов, лучше делать это последовательно, небольшими шагами (например, по 2-3 релиза), а не пытаться обновить сразу до последней версии.
  3. Завершите все обмены данными. Перед началом обновления убедитесь, что все обмены данными между узлами завершены. Если штатный механизм РИБ дает сбои, можно рассмотреть обмен данными через DBF. Это поможет избежать потери данных и конфликтов при обновлении.
  4. Информируйте пользователей и заблокируйте работу. Рекомендуется уведомить всех пользователей о предстоящем обновлении и попросить их завершить работу в базах данных. На время обновления доступ к базам должен быть ограничен, чтобы избежать ошибок из-за активных сеансов.
  5. Проверьте конфигурацию на типовость и поддержку. Убедитесь, что ваша конфигурация типовая и находится на поддержке. Любые нетиповые изменения или некорректно выполненные обновления могут стать причиной проблем, в том числе при управлении дополнительными реквизитами. Также проверьте, соответствует ли версия конфигурации поставщика текущей версии информационной базы.

Анализ причины ошибки "В данной транзакции уже происходили ошибки!"

Сообщение "В данной транзакции уже происходили ошибки!" не является первопричиной проблемы, а лишь ее следствием. Оно означает, что на более раннем этапе внутри текущей транзакции произошло какое-то исключение, и СУБД пометила эту транзакцию как "испорченную" (или "только для отмены" - rollback only). Любая последующая попытка выполнить операцию с базой данных в рамках этой же транзакции приведет к выдаче данного сообщения.

Часто эта ошибка возникает при попытке проведения документа "Ввод начальных остатков узла", который передается в периферийный узел (иногда это путают с загрузкой остатков из Розницы 2.2). Проблема может быть связана с некорректными данными в этом документе, дублирующимися строками, или спецификой обработки этого документа в обновленной конфигурации.

Для более точного определения места возникновения исходной ошибки (до того, как транзакция стала "испорченной") мы рекомендуем использовать технологический журнал 1С. Настройте в нем фильтрацию по событиям SDBL с параметром Func = "setRollbackOnly", а также по событию EXCP. Это поможет выявить участок кода, где транзакции был присвоен статус "только для отмены", и найти истинную причину проблемы.

Решение 1: Временное комментирование кода, связанного с документом "Ввод начальных остатков узла"

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

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

Разберем по шагам, как это сделать:

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

    Обратите внимание на строку Пока ВыборкаДокументов.Следующий Цикл. Именно в этом цикле при попытке обработки существующего документа может возникнуть ошибка.

  5. Закомментируйте проблемный код. Временно закомментируйте весь блок кода, который занимается проведением документов ВводНачальныхОстатковУзла. Это можно сделать, добавив // перед каждой строкой или используя блоки #Если &НеИспользованиеРИБ Тогда ... #КонецЕсли, но для временного решения достаточно просто закомментировать.
    
    // Начало закомментированного блока для обхода ошибки при обновлении РИБ
    // ВыборкаДокументов = Документы.ВводНачальныхОстатковУзла.Выбрать(,, Новый Структура("КодУзлаОбмена", ПредопределенныйУзел.Код), "Дата");
    // Пока ВыборкаДокументов.Следующий Цикл
    //     ДокументВыборки = ВыборкаДокументов.ПолучитьОбъект;
    //     Если ДокументВыборки <> Неопределено И НЕ ДокументВыборки.ПометкаУдаления И НЕ ДокументВыборки.Проведен Тогда
    //         ДокументВыборки.Узел = Ссылка;
    //         Если НЕ ОбменДаннымиПереопределяемый.ЗаписатьВводОстатков(ДокументВыборки, РежимЗаписиДокумента.Проведение) Тогда
    //             Отказ = Истина;
    //         КонецЕсли;
    //     КонецЕсли;
    // КонецЦикла;
    // Конец закомментированного блока
    
  6. Сохраните изменения и обновите базу. После комментирования сохраните конфигурацию базы данных. Затем запустите процесс обновления периферийного узла. Мы ожидаем, что теперь обновление пройдет успешно, поскольку проблемный участок кода будет игнорироваться.
  7. Раскомментируйте код после обновления. После успешного обновления периферийного узла и завершения обмена, обязательно верните закомментированный код на место. Откройте МодульОбъекта плана обмена, раскомментируйте строки, сохраните конфигурацию базы данных и обновите конфигурацию базы данных. Это важно для обеспечения корректной работы РИБ в дальнейшем.

Решение 2: Отвязка периферийного узла, обновление через файл конфигурации (.cf) и повторная привязка

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

Мы рекомендуем использовать этот подход, если предыдущее решение с комментированием кода не дало результата, или если вы имеете дело с очень большим количеством пропущенных релизов, что усложняет последовательное обновление.

Разберем процесс по шагам:

  1. Создайте резервную копию периферийного узла. Перед любыми манипуляциями с РИБ всегда делайте полную резервную копию.
  2. Обновите центральную базу. Убедитесь, что центральный узел РИБ полностью обновлен до целевого релиза и работает стабильно.
  3. Сохраните конфигурацию центральной базы в файл .cf. В конфигураторе центральной базы выберите "Конфигурация" -> "Сохранить конфигурацию в файл..." и сохраните актуальную конфигурацию в файл с расширением .cf.
  4. Отвяжите периферийный узел от РИБ. В конфигураторе периферийного узла выполните следующие действия:
    • Перейдите в меню "Все функции" (обычно доступно через "Сервис" -> "Параметры" -> "Отображать команду 'Все функции'").
    • Найдите и откройте константу ГлавныйУзел. Установите ее в пустое значение (Не определено).
    • Найдите и откройте константу НастройкаПодчиненногоУзлаЗавершена. Снимите флажок или установите ее в Ложь.
    • Также может потребоваться удалить установленные патчи исправлений и расширения конфигурации, чтобы минимизировать потенциальные конфликты.
    • Сохраните изменения в конфигурации базы данных.

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

  5. Обновите периферийный узел загрузкой .cf файла. В конфигураторе периферийного узла выберите "Конфигурация" -> "Загрузить конфигурацию из файла..." и укажите сохраненный ранее .cf файл центральной базы. Согласитесь на все изменения и обновите конфигурацию базы данных. Теперь периферийный узел будет иметь актуальную конфигурацию.
  6. Повторно привяжите периферийный узел к центральной базе. Этот шаг требует создания нового начального образа обмена:
    • В центральной базе зайдите в раздел "Администрирование" -> "Настройка синхронизации данных" -> "Узлы РИБ" (или аналогичный путь, в зависимости от релиза).
    • Создайте новый узел для вашего магазина (или используйте существующий, если он остался, но он должен быть помечен как "Необходимо создать начальный образ").
    • Запустите процесс создания начального образа для этого узла. Система сформирует файл обмена (например, Central_to_Shop_N.zip).
    • В периферийной базе запустите программу в режиме "Предприятие". Перейдите в раздел "Администрирование" -> "Настройка синхронизации данных".
    • Выберите пункт "Загрузить данные из файла" (или аналогичный). Укажите файл начального образа, созданный на предыдущем шаге.
    • Система проведет первичную синхронизацию и настроит периферийный узел как подчиненный.

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

Решение 3: Корректировка документа "Ввод начальных остатков узла"

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

Выясним возможные причины, среди которых часто требуется поиск и восстановление битых ссылок:

Рассмотрим варианты корректировки:

  1. Программная очистка табличных частей. Вы можете написать небольшую внешнюю обработку или выполнить код в конфигураторе для очистки определенных табличных частей в документах ВводНачальныхОстатковУзла. Например, если проблема в ценах номенклатуры, можно очистить табличную часть ЦеныНоменклатуры.
  2. 
    // Пример кода для очистки табличной части "ЦеныНоменклатуры"
    // ВНИМАНИЕ: Выполняйте этот код на резервной копии и с полным пониманием его работы!
    // Откройте базу в режиме конфигуратора
    // Запустите "Выполнить произвольный код" или создайте временную обработку
    
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ССЫЛКА
                   |ИЗ Документ.ВводНачальныхОстатковУзла
                   |ГДЕ Истина"; // Можно добавить условия для отбора конкретных документов
    
    ВыборкаДокументов = Запрос.Выполнить().Выбрать();
    
    Пока ВыборкаДокументов.Следующий() Цикл
        Попытка
            ДокументОбъект = ВыборкаДокументов.ССЫЛКА.ПолучитьОбъект();
            Если ДокументОбъект.ЦеныНоменклатуры.Количество() > 0 Тогда
                ДокументОбъект.ЦеныНоменклатуры.Очистить();
                ДокументОбъект.Записать();
                Сообщить("В документе " + ДокументОбъект.Номер + " от " + ДокументОбъект.Дата + " очищена табличная часть ЦеныНоменклатуры.");
            КонецЕсли;
        Исключение
            Сообщить("Ошибка при обработке документа " + ВыборкаДокументов.ССЫЛКА + ": " + ОписаниеОшибки());
        КонецПопытки;
    КонецЦикла;
    
  3. Поиск и удаление дублирующих строк. Если проблема точно в дублях, мы можем вручную или программно найти и удалить дублирующие строки на соответствующих закладках документа "Ввод начальных остатков узла" (например, ЦеныНоменклатуры). После удаления дублей обязательно зарегистрируйте данный документ к выгрузке (если он должен участвовать в обмене) и попробуйте провести обмен снова.
  4. Пометка на удаление документов "Ввод начальных остатков узла". Если эти документы не критичны для текущей работы периферийного узла и вы готовы к их пересозданию или игнорированию, вы можете пометить на удаление все документы ВводНачальныхОстатковУзла в периферийном узле через "Все функции" -> "Стандартные" -> "Удаление помеченных объектов" (после пометки их на удаление). Это может помочь, если именно их наличие или попытка проведения вызывает конфликт при обновлении.

Решение 4: Изменение даты запрета изменения данных

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

Рассмотрим шаги, как это сделать:

  1. Установите дату запрета изменения данных. В центральной базе или в периферийном узле (в зависимости от того, где происходит конфликт) временно снимите или установите дату запрета изменения данных для всех пользователей на дату документа "Ввод начальных остатков узла". Цель состоит в том, чтобы сделать период, в котором датирован этот документ, открытым для записи.
  2. Попробуйте провести обмен/обновление. После изменения даты запрета запустите процесс обмена данными или продолжите обновление. Если проблема была связана с запретом изменений, то теперь она может быть устранена.
  3. Верните дату запрета на место. После успешного обновления или обмена обязательно верните дату запрета изменения данных на ее исходное, корректное значение для обеспечения целостности и безопасности данных.

Мы видим, что проблема обновления РИБ в 1С:Рознице с ошибкой "В данной транзакции уже происходили ошибки!" является достаточно комплексной и может быть вызвана разными причинами, часто связанными с обработкой документа ВводНачальныхОстатковУзла. Мы разобрали несколько действенных решений: от временного комментирования кода до полной переинициализации узла и корректировки данных. Всегда помните о необходимости создания резервных копий и тестировании любых изменений на копии базы данных перед применением на рабочей системе.

← На главную