---
name: bsp-update
description: "Use this skill when the agent needs to add an update handler to a configuration, run database update programmatically, check whether an update is required or in progress, register pre-defined elements for update, get or set the infobase version for a subsystem, prepare patch changes before a configuration update, write data inside an update handler without triggering business logic, or implement a hook called before or after the infobase update. Do not use for routine object recording outside an update handler (delegate to bsp-base-common), for routine jobs and background operations (delegate to bsp-longs-and-jobs), or for adding business logic to a configuration (out of scope)."
metadata:
  scope: bsp-3.1.11
  version: "3.1.11"
  layer: L3
  related_subsystems:
    - ОбновлениеВерсииИБ
    - ОбновлениеКонфигурации
  related_skills:
    - bsp-fundamentals
    - bsp-base-common
---

# bsp-update — Обновление версии ИБ и обновление конфигурации

Скил по подсистемам «Обновление версии ИБ» (в блоке `БазоваяФункциональность`) и «Обновление конфигурации». Покрывает **обработчики обновления** (Монопольно / Оперативно / Отложенно), **миграцию данных** при смене версии конфигурации или библиотеки, а также **управление версиями ИБ** через регистр сведений `ВерсииПодсистем`.

Главная задача скила — научить агента правильно писать BSL-код **внутри** обработчика обновления (правильные обёртки записи), правильно **регистрировать** обработчики (через `НоваяТаблицаОбработчиковОбновления`), и не путать `Переопределение`-модули (содержат «крючки» для прикладной конфигурации) с модулями, которые нужно **вызывать**.

## When to use

- Написать **новый обработчик обновления** прикладной конфигурации (для конкретной версии, для версии `*`, или с начальным заполнением) и зарегистрировать его в `ПриДобавленииОбработчиковОбновления`.
- Программно **запустить обновление** из кода (например, из внешней обработки) — неинтерактивный пакетный режим.
- Проверить из прикладного кода, **требуется ли обновление**, или **выполняется ли оно прямо сейчас** (чтобы безопасно отказать в записи или показать предупреждение).
- Прочитать / записать **версию ИБ** для конкретной подсистемы или для основной конфигурации (например, чтобы зафиксировать, что миграция данных уже выполнена, без запуска штатных обработчиков).
- Безопасно **записать объект, набор записей или константу** в обработчике обновления — без бизнес-логики и без регистрации на планах обмена (или, наоборот, с принудительной регистрацией).
- Проверить, **заблокирован ли объект для редактирования** до завершения отложенной обработки (функция `ДанныеОбновленыНаНовуюВерсиюПрограммы` используется как стандартная проверка блокировки в формах объектов).
- Реализовать **переопределяемый крючок** БСП в прикладной конфигурации: `ПередОбновлениемИнформационнойБазы`, `ПослеОбновленияИнформационнойБазы`, `ПриОпределенииВозможностиОбновления`.
- Подготовить **патчи (исправления)** к пакетному обновлению — удалить устаревшие, установить корректные свойства новым.

## Не использовать, если

- Нужна **обычная запись объектов вне обработчика обновления** — это `bsp-base-common` (`ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище`, `ОбщегоНазначения.СообщитьПользователю` и т. п.). Обёртки `ОбновлениеИнформационнойБазы.ЗаписатьОбъект` / `ЗаписатьДанные` / `ЗаписатьНаборЗаписей` / `УдалитьДанные` предназначены **только** для кода внутри обработчика обновления: они не вызывают бизнес-логику и не регистрируют на планах обмена по умолчанию. Использовать их для прикладной логики проведения документов — **анти-паттерн** (см. Anti-patterns).
- Нужно запустить **фоновое задание, регламентное задание, длительную операцию** — `bsp-longs-and-jobs`. `ОбновлениеИнформационнойБазы` умеет делать обработку в несколько потоков, но это **внутренний** механизм отложенного обновления, а не публичный API для фоновых задач прикладного кода.
- Нужна **настройка подсистемы в дереве метаданных** (внедрение БСП, подключение к прикладной конфигурации, перенос подсистем) — задача архитектора конфигурации, не покрывается этим скилом.
- Нужна **миграция данных вне обновления** (например, разовый перенос данных при переходе с другой программы) — используйте `ОбновлениеИнформационнойБазы.ЗаписатьОбъект` / `УдалитьДанные` для записей внутри обработчика, а саму логику переноса оформляйте как штатный обработчик обновления. Если перенос разовый и обработчик уже сработал — он повторно не вызывается; используйте ручной сценарий через `ВыполнитьОбновлениеИнформационнойБазы` с `Отложенно = Ложь` или перезапустите отложенный обработчик через `ПерезапуститьОтложенноеОбновление`.

## Core concepts

### Архитектура подсистемы «Обновление версии ИБ»

Подсистема лежит в блоке `БазоваяФункциональность` и обслуживается **семейством** общих модулей `ОбновлениеИнформационнойБазы*` (без префикса, с суффиксами). Все экспортные методы, которые вызывает прикладной код, находятся в **стабильной** области `Программный интерфейс` модуля `ОбновлениеИнформационнойБазы` (Сервер + Внешнее соединение + Толстый клиент, без клиентского). Служебные модули `*Служебный` — **внутренний** API (⚠️ обратная совместимость не гарантируется), используются другими модулями БСП.

Полная карта модулей семейства:

| Модуль | Контекст | Назначение |
|---|---|---|
| `ОбновлениеИнформационнойБазы` | Сервер, Внешнее соединение, Толстый клиент | **Стабильный API**: запуск обновления, версии ИБ, таблицы обработчиков, обёртки записи, логирование, журнал регистрации |
| `ОбновлениеИнформационнойБазыКлиент` | Клиент | Показ форм отложенных обработчиков, индикация хода обновления, инициация интерактивного обновления |
| `ОбновлениеИнформационнойБазыГлобальный` | Глобальный | `ПроверитьСтатусОтложенногоОбновления` — вызывается по имени, без префикса модуля |
| `ОбновлениеИнформационнойБазыВызовСервера` | Серверный вызов с клиента | Серверный вызов `ВыполнитьОбновлениеИнформационнойБазы` без контекста формы |
| `ОбновлениеИнформационнойБазыПереопределяемый` | Сервер | «Крючки» прикладной конфигурации: `ПередОбновлениемИнформационнойБазы`, `ПослеОбновленияИнформационнойБазы`, `ПриОпределенииНастроек`, `ПриОпределенииПроверок` и т. п. **Не вызывать**, **реализовывать** в прикладном коде |
| `ОбновлениеИнформационнойБазыКлиентПереопределяемый` | Клиент | Клиентские крючки: `ПриОпределенииВозможностиОбновления`, `ПриНажатииНаГиперссылкуВДокументеОписанияОбновлений` |
| `ОбновлениеИнформационнойБазыСлужебный` | Сервер | ⚠️ **Служебный API**: внутренняя логика итераций обновления, блокировка ИБ, фоновое обновление. Обратная совместимость не гарантируется. Не вызывайте из прикладного кода, если в стабильном `ОбновлениеИнформационнойБазы` есть аналог |
| `ОбновлениеИнформационнойБазыСлужебныйВызовСервера` | Серверный вызов | ⚠️ `ВыполнитьОбновлениеИнформационнойБазы(ПриЗапускеКлиентскогоПриложения, …)` с тремя параметрами — для системных сценариев, не для прикладного вызова |
| `ОбновлениеИнформационнойБазыСлужебныйПовтИсп` | Сервер, кэш | ⚠️ Внутренние кэши: `МинимальнаяВерсияИБ`, `ОчередьОтложенногоОбработчикаОбновления`. Не вызывать |

⚠️ **Не существует** модуля `ОбновлениеИнформационнойБазыСервер` (с суффиксом `Сервер`): серверный модуль — `ОбновлениеИнформационнойБазы` (без суффикса). Сравните: `РегламентныеЗадания` (без суффикса) тоже не существует, серверный — `РегламентныеЗаданияСервер`. **Перед вызовом сверяйтесь с реальным каталогом общих модулей в выгрузке конфигурации.**

### Архитектура подсистемы «Обновление конфигурации»

Отдельная подсистема, отвечает за **интерактивную установку** обновлений конфигурации (через Конфигуратор в пакетном режиме) и **исправления (патчи)**. Используется редко в прикладном коде; основной потребитель — сама БСП и администратор.

Полная карта модулей:

| Модуль | Контекст | Назначение |
|---|---|---|
| `ОбновлениеКонфигурации` | Сервер, Внешнее соединение, Толстый клиент | `ИсправленияИзменены`, `УстановленныеИсправления`, `УстановкаИУдалениеИсправлений`, `НастройкиОбновленияКонфигурации`, `ЗавершитьОбновление` |
| `ОбновлениеКонфигурацииКлиент` | Клиент | `ПоддерживаетсяУстановкаОбновлений`, `ПоказатьПоискИУстановкуОбновлений`, `ПоказатьУстановленныеИсправления` |
| `ОбновлениеКонфигурацииГлобальный` | Глобальный | Обработчик ожидания `ОбработчикОжиданияУстановитьОбновлениеСейчас` |
| `ОбновлениеКонфигурацииВызовСервера` | Серверный вызов | `НаличиеАктивныхСоединений`, `ТекстыМакетов`, `СохранитьНастройкиОбновленияКонфигурации` |

### Обработчики обновления — три режима выполнения

Подсистема «Обновление версии ИБ» поддерживает **три режима** выполнения обработчиков. Это влияет на сигнатуру, на наличие блокировки ИБ, и на порядок относительно других обработчиков.

| Режим | Когда выполняется | Особенности |
|---|---|---|
| `Монопольно` | При запуске с блокировкой ИБ. По умолчанию, если в строке таблицы не указан режим | Требует монопольного режима. Допускается тяжёлая миграция данных |
| `Оперативно` | При запуске без блокировки ИБ (оперативное обновление) | Может выполняться во время работы пользователей. Допускается только лёгкая миграция, иначе — отказ в пользу монопольного |
| `Отложенно` | После основного цикла, в фоне, в несколько потоков | Требует `Идентификатор`, `БлокируемыеОбъекты`, `ПроцедураПроверки`. Использует регистр сведений `ОбновляемыеОбъекты` для регистрации данных, подлежащих обработке |
| `Параллельно` | Специальный режим отложенного обновления для библиотек с параллельным режимом | Дополнительные колонки: `Многопоточный`, `ЗапускатьТолькоВГлавномУзле`, `ЧитаемыеОбъекты`, `ИзменяемыеОбъекты` |

Структура таблицы обработчиков и набор колонок для каждого режима — функция `ОбновлениеИнформационнойБазы.НоваяТаблицаОбработчиковОбновления`.

### Версионирование конфигурации

Каждая библиотека (включая основную конфигурацию) хранит свою версию в регистре сведений `ВерсииПодсистем`. При запуске подсистема сравнивает версию конфигурации (`Метаданные.Версия`) с версией в ИБ и выполняет обработчики, у которых номер версии больше сохранённого. Версия `*` означает **обязательный обработчик**, который выполняется при каждом обновлении.

Ключевые методы работы с версиями:

- `ВерсияИБ(ИмяПодсистемы)` — прочитать сохранённую версию.
- `УстановитьВерсиюИБ(ИмяПодсистемы, НомерВерсии, ЭтоОсновнаяКонфигурация)` — записать версию.
- `ВерсииПодсистем()` — прочитать все версии таблицей (используется в `ПередОбновлениемИнформационнойБазы`).
- `УстановитьВерсииПодсистем(ВерсииПодсистем)` — записать набор версий.
- `ЗарегистрироватьНовуюПодсистему(ИмяПодсистемы, НомерВерсии)` — зарегистрировать **новую** подсистему, не выполняя для неё обработчики начального заполнения. Вызывать из `ПередОбновлениемИнформационнойБазы`.

### Регистрация обработчиков

Обработчики регистрируются в процедуре `ПриДобавленииОбработчиковОбновления` модуля `ОбновлениеИнформационнойБазыСлужебный` (⚠️ служебный — модуль БСП, не прикладной код) — это **служебный крючок** БСП. Прикладная конфигурация реализует аналогичную процедуру в собственном модуле `ОбновлениеИнформационнойБазы<Префикс>` (например, `ОбновлениеИнформационнойБазыУПП`), и регистрирует его через `РегламентныеЗаданияСервер` или специальную процедуру подключения обработчиков (см. документацию к прикладной конфигурации). В рамках этого скила — достаточно знать **сигнатуру таблицы обработчиков** и **правила заполнения колонок**.

### Миграция данных внутри обработчика

Запись данных из обработчика обновления — **особый** случай. Прямой `Объект.Записать()` или `НаборЗаписей.Записать()` внутри обработчика **не рекомендуется**:

- `Записать()` триггерит подписки на события и обработчики модуля объекта → может вызвать бизнес-логику, которая ещё не готова к работе в момент обновления (например, проверки заполнения, основанные на ещё не мигрированных реквизитах).
- `Записать()` регистрирует объект на всех планах обмена → миграция данных разлетится по узлам РИБ.

Вместо этого используются **обёртки** `ОбновлениеИнформационнойБазы.ЗаписатьДанные`, `ЗаписатьОбъект`, `ЗаписатьНаборЗаписей`, `УдалитьДанные` с параметрами:

- `РегистрироватьНаУзлахПлановОбмена` — `Неопределено` (по умолчанию) означает «использовать стандартное поведение подсистемы обновления» (обычно **не** регистрировать, чтобы миграция данных не уходила в обмен). Передавайте `Истина`, только если миграция должна попасть в обмен.
- `ВключитьБизнесЛогику` — `Ложь` (по умолчанию) отключает обработчики модуля объекта и подписки на события. Передавайте `Истина`, только если это явно нужно.

### Журнал регистрации из обработчика

Для логирования хода обновления используются методы `ЗаписатьСобытиеВЖурналРегистрации` (информационное) и `ЗаписатьОшибкуВЖурналРегистрации` (ошибка). Событие журнала — фиксированная строка, общая для всех обработчиков (`СобытиеЖурналаРегистрации`).

## Key methods

| Метод | Сигнатура | Сервер/Клиент | Стабильность | Назначение | Пример вызова |
|---|---|---|---|---|---|
| `ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы` | `ВыполнитьОбновлениеИнформационнойБазы(ВыполнятьОтложенныеОбработчики = Ложь)` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Запустить неинтерактивное обновление. Перед вызовом — `ОбновлениеКонфигурации.ИсправленияИзменены()`. Возвращает: `"Успешно" / "НеТребуется" / "ОшибкаУстановкиМонопольногоРежима"` | `Результат = ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы();` |
| `ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы` | `НеобходимоОбновлениеИнформационнойБазы()` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Проверить, требуется ли обновление после смены версии конфигурации | `Если ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы() Тогда ...` |
| `ОбновлениеИнформационнойБазы.ВыполняетсяОбновлениеИнформационнойБазы` | `ВыполняетсяОбновлениеИнформационнойБазы()` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Проверить, что обновление выполняется прямо сейчас (например, чтобы отказать в записи документа) | `Если ОбновлениеИнформационнойБазы.ВыполняетсяОбновлениеИнформационнойБазы() Тогда Отказ = Истина;` |
| `ОбновлениеИнформационнойБазы.ВерсияИБ` | `ВерсияИБ(Знач ИдентификаторБиблиотеки)` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Прочитать сохранённую версию ИБ для подсистемы или основной конфигурации | `ТекущаяВерсия = ОбновлениеИнформационнойБазы.ВерсияИБ(Метаданные.Имя);` |
| `ОбновлениеИнформационнойБазы.УстановитьВерсиюИБ` | `УстановитьВерсиюИБ(Знач ИдентификаторБиблиотеки, Знач НомерВерсии, Знач ЭтоОсновнаяКонфигурация)` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Записать версию ИБ без выполнения обработчиков (например, в `ПередОбновлениемИнформационнойБазы` для отмены штатного обновления) | `ОбновлениеИнформационнойБазы.УстановитьВерсиюИБ(Метаданные.Имя, Метаданные.Версия, Истина);` |
| `ОбновлениеИнформационнойБазы.ЗаписатьДанные` | `ЗаписатьДанные(Знач Данные, Знач РегистрироватьНаУзлахПлановОбмена = Неопределено, Знач ВключитьБизнесЛогику = Ложь)` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Записать объект / набор записей / константу из обработчика обновления. **Только** для кода внутри обработчика. По умолчанию без бизнес-логики и без регистрации на планах обмена | `ОбновлениеИнформационнойБазы.ЗаписатьДанные(Объект);` |
| `ОбновлениеИнформационнойБазы.ЗаписатьОшибкуВЖурналРегистрации` | `ЗаписатьОшибкуВЖурналРегистрации(СсылкаМетаданные, Знач Представление, ИнформацияОбОшибке = Неопределено, Уровень = Неопределено)` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Записать ошибку в журнал регистрации с привязкой к событию обновления | `ОбновлениеИнформационнойБазы.ЗаписатьОшибкуВЖурналРегистрации(Метаданные.Справочники.Контрагенты, "Не удалось заполнить реквизит", ИнформацияОбОшибке());` |
| `ОбновлениеИнформационнойБазы.ПерезапуститьОтложенноеОбновление` | `ПерезапуститьОтложенноеОбновление(Отбор = Неопределено)` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Перезапустить ранее отложенный обработчик (например, после исправления данных в основном потоке) | `ОбновлениеИнформационнойБазы.ПерезапуститьОтложенноеОбновление(Новый Структура("ИмяОбработчика", "МойОбработчик"))` |
| `ОбновлениеКонфигурации.ИсправленияИзменены` | `ИсправленияИзменены(ТолькоПроверка = Ложь)` | Сервер, Внешнее соединение, Толстый клиент | стабильный | Удалить устаревшие патчи и применить новые **перед** пакетным обновлением. Возвращает: `ЕстьИзменения`, `ОписаниеИзменений` | `ОбновлениеКонфигурации.ИсправленияИзменены();` |
| `ОбновлениеКонфигурацииКлиент.ПоддерживаетсяУстановкаОбновлений` | `ПоддерживаетсяУстановкаОбновлений()` | Клиент | стабильный | Проверить, поддерживается ли интерактивная установка обновлений на текущем рабочем месте (ОС Windows + Конфигуратор + права администратора; не модель сервиса) | `Результат = ОбновлениеКонфигурацииКлиент.ПоддерживаетсяУстановкаОбновлений();` |

> **Полный список** (13 методов, включая `НоваяТаблицаОбработчиковОбновления`, `ДанныеОбновленыНаНовуюВерсиюПрограммы`, `ОбновлениеИнформационнойБазыСлужебный.ПараметрыОбновления`) — в [`references/key-methods.md`](references/key-methods.md).

### Переопределяемые модули (НЕ вызывать, а реализовывать)

| Метод (переопределяемый) | Сигнатура | Контекст | Назначение | Где реализуется |
|---|---|---|---|---|
| `ПередОбновлениемИнформационнойБазы` | `ПередОбновлениемИнформационнойБазы()` | Сервер, Внешнее соединение, Толстый клиент | Вызывается **перед** запуском обработчиков обновления. Можно зафиксировать версии подсистем, отменить штатный переход с другой программы | `ОбновлениеИнформационнойБазыПереопределяемый` |
| `ПослеОбновленияИнформационнойБазы` | `ПослеОбновленияИнформационнойБазы(Знач ПредыдущаяВерсияИБ, Знач ТекущаяВерсияИБ, Знач ИтерацииОбновления, ВыводитьОписаниеОбновлений, Знач МонопольныйРежим)` | Сервер, Внешнее соединение, Толстый клиент | Вызывается **после** завершения обновления. Можно отключить показ формы описания изменений (`ВыводитьОписаниеОбновлений = Ложь`) | `ОбновлениеИнформационнойБазыПереопределяемый` |
| `ПриОпределенииВозможностиОбновления` | `ПриОпределенииВозможностиОбновления(Знач ВерсияДанных)` | Тонкий клиент, Толстый клиент | Проверка возможности обновления на текущую версию в `ПередНачаломРаботыСистемы` | `ОбновлениеИнформационнойБазыКлиентПереопределяемый` |
| `ПриОпределенииНастроек` | `ПриОпределенииНастроек(Параметры)` | Сервер, Внешнее соединение, Толстый клиент | Переопределение общих настроек подсистемы обновления | `ОбновлениеИнформационнойБазыПереопределяемый` |
| `ПриОпределенииПроверок` | `ПриОпределенииПроверок(ГруппыПроверок, Проверки)` | Сервер, Внешнее соединение, Толстый клиент | Регистрация собственных проверок блокировки объектов | `ОбновлениеИнформационнойБазыПереопределяемый` |

## Patterns

### 1. Регистрация обработчика обновления в прикладной конфигурации

Типовая структура модуля `ОбновлениеИнформационнойБазыУПП` (прикладной модуль обработчиков):

```bsl
// ОбновлениеИнформационнойБазыУПП
#Область ПрограммныйИнтерфейс

Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
    
    Обработчик = Обработчики.Добавить();
    Обработчик.Версия              = "2.4.1.5";
    Обработчик.Процедура           = "ОбновлениеИнформационнойБазыУПП.ЗаполнитьНовыйРеквизит";
    Обработчик.РежимВыполнения     = "Монопольно";
    
    Обработчик = Обработчики.Добавить();
    Обработчик.Версия              = "*";  // обязательный, выполняется при каждом обновлении
    Обработчик.Процедура           = "ОбновлениеИнформационнойБазыУПП.ОбновитьКонтактнуюИнформацию";
    Обработчик.РежимВыполнения     = "Отложенно";
    Обработчик.Идентификатор       = Новый УникальныйИдентификатор("a1b2c3d4-...");
    Обработчик.Комментарий         = "Обновление КИ по новому формату";
    Обработчик.БлокируемыеОбъекты  = "Справочник.Контрагенты";
    Обработчик.ПроцедураПроверки   = "ОбновлениеИнформационнойБазыУПП.КонтрагентОбработан";
    
КонецПроцедуры

Процедура ЗаполнитьНовыйРеквизит() Экспорт
    // Миграция данных на новую версию
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Контрагенты ГДЕ НовыйРеквизит = """";
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Контрагент = Выборка.Ссылка.ПолучитьОбъект();
        Контрагент.НовыйРеквизит = "ЗначениеПоУмолчанию";
        ОбновлениеИнформационнойБазы.ЗаписатьДанные(Контрагент);
    КонецЦикла;
КонецПроцедуры

#КонецОбласти
```

⚠️ **Важно:** сам модуль `ОбновлениеИнформационнойБазыСлужебный` БСП содержит `ПриДобавленииОбработчиковОбновления` — это **внутренний крючок БСП**, не место для прикладных обработчиков. Прикладная конфигурация имеет собственный модуль с префиксом (`ОбновлениеИнформационнойБазыУПП`, `ОбновлениеИнформационнойБазыБП` и т. п.).

### 2. Безопасная запись данных из обработчика обновления

```bsl
Процедура ОбновитьРеквизитДокумента() Экспорт
    Выборка = Документы.Заказ.Выбрать();
    Пока Выборка.Следующий() Цикл
        ДокументОбъект = Выборка.ПолучитьОбъект();
        ДокументОбъект.НовыйРеквизит = "...";
        // Бизнес-логика ОТКЛЮЧЕНА, регистрация на планах обмена НЕ выполняется
        ОбновлениеИнформационнойБазы.ЗаписатьДанные(ДокументОбъект);
    КонецЦикла;
КонецПроцедуры
```

Если нужна запись **с включённой бизнес-логикой** (для документов, у которых миграция данных не нарушает логику проведения), — `ОбновлениеИнформационнойБазы.ЗаписатьОбъект(ДокументОбъект, , Истина, РежимЗаписиДокумента.Проведение)`. Третий параметр — `ВключитьБизнесЛогику = Истина`, четвёртый — режим записи документа.

### 3. Проверка блокировки объекта в форме

Стандартный приём — подключить `ДанныеОбновленыНаНовуюВерсиюПрограммы` как функцию проверки блокировки для отложенного обработчика. В форме объекта:

```bsl
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если НЕ ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы(
        ОбновлениеИнформационнойБазы.МетаданныеИОтборПоДанным(Объект)) Тогда
        Текст = НСтр("ru = 'Объект заблокирован для редактирования до завершения обновления.'");
        ОбщегоНазначения.СообщитьПользователю(Текст, , , , Отказ);
    КонецЕсли;
КонецПроцедуры
```

### 4. Программный запуск обновления (пакетный режим)

```bsl
// В обработке, вызываемой из внешнего соединения
ОбновлениеКонфигурации.ИсправленияИзменены();  // удалить устаревшие патчи
Результат = ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы();
Если Результат = "ОшибкаУстановкиМонопольногоРежима" Тогда
    // повторить позже или сообщить администратору
КонецЕсли;
```

### 5. Переопределение: отмена штатного перехода с другой программы

В `ОбновлениеИнформационнойБазыПереопределяемый`:

```bsl
Процедура ПередОбновлениемИнформационнойБазы() Экспорт
    ВерсииПодсистем = ОбновлениеИнформационнойБазы.ВерсииПодсистем();
    Если ВерсииПодсистем.Количество() > 0
        И ВерсииПодсистем.Найти(Метаданные.Имя, "ИмяПодсистемы") = Неопределено Тогда
        // Регистрация основной конфигурации как уже актуальной версии —
        // штатный переход с другой программы отменяется
        ОбновлениеИнформационнойБазы.ЗарегистрироватьНовуюПодсистему(
            Метаданные.Имя, Метаданные.Версия);
    КонецЕсли;
КонецПроцедуры
```

### 6. Подготовка к интерактивному обновлению конфигурации

```bsl
// На клиенте, в обработчике команды
Если ОбновлениеКонфигурацииКлиент.ПоддерживаетсяУстановкаОбновлений().Поддерживается Тогда
    ОбновлениеКонфигурацииКлиент.ПоказатьПоискИУстановкуОбновлений(
        Новый Структура("ЗавершениеРаботыСистемы", Истина));
КонецЕсли;
```

## Anti-patterns

### ❌ Использовать прямые методы записи в обработчике обновления

```bsl
// ❌ Прямой вызов Записать() внутри обработчика обновления
Процедура МойОбработчик() Экспорт
    ДокументОбъект = Документ.Заказ.НайтиПоНомеру("001").ПолучитьОбъект();
    ДокументОбъект.Реквизит = "...";
    ДокументОбъект.Записать();  // триггерит бизнес-логику и регистрацию обмена
КонецПроцедуры
```

```bsl
// ✅ Обёртка подсистемы обновления — без бизнес-логики, без регистрации обмена
Процедура МойОбработчик() Экспорт
    ДокументОбъект = Документ.Заказ.НайтиПоНомеру("001").ПолучитьОбъект();
    ДокументОбъект.Реквизит = "...";
    ОбновлениеИнформационнойБазы.ЗаписатьДанные(ДокументОбъект);
КонецПроцедуры
```

### ❌ Вызывать переопределяемый модуль

```bsl
// ❌ ОШИБКА КОМПИЛЯЦИИ: модуль Переопределяемый не содержит вызываемых экспортных функций
// для сценария «дёрнуть штатный крючок из прикладного кода»
Результат = ОбновлениеИнформационнойБазыПереопределяемый.ПередОбновлениемИнформационнойБазы();
```

```bsl
// ✅ Переопределяемые модули только реализуют, не вызывают.
// Если нужно зафиксировать версию до обновления — используйте прямые API:
ОбновлениеИнформационнойБазы.УстановитьВерсиюИБ(Метаданные.Имя, "1.0.0.0", Истина);
```

### ❌ Запускать обновление при работающих пользователях (интерактивный режим)

```bsl
// ❌ Из клиентского кода пытаемся запустить обновление напрямую
ОбновлениеИнформационнойБазыВызовСервера.ВыполнитьОбновлениеИнформационнойБазы(Истина);
```

```bsl
// ✅ Для интерактивной установки — клиентская обёртка подсистемы ОбновлениеКонфигурации
// (открывает форму с предложением обновить, учитывает блокировки, делает бэкап)
ОбновлениеКонфигурацииКлиент.ПоказатьПоискИУстановкуОбновлений();

// ✅ Для пакетного режима (из внешнего соединения) — сначала патчи, потом обновление
ОбновлениеКонфигурации.ИсправленияИзменены();
ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы();
```

### ❌ Забыть `ЭтоОсновнаяКонфигурация` в `УстановитьВерсиюИБ`

```bsl
// ❌ Не указан признак «это основная конфигурация» — версия запишется в библиотечную ветку
ОбновлениеИнформационнойБазы.УстановитьВерсиюИБ(Метаданные.Имя, "1.0.0.0");
```

```bsl
// ✅ Явный признак: Истина для основной конфигурации, Ложь для библиотеки
ОбновлениеИнформационнойБазы.УстановитьВерсиюИБ(Метаданные.Имя, "1.0.0.0", Истина);
```

### ❌ Использовать `ОбновлениеИнформационнойБазыСлужебный` для прикладных задач

```bsl
// ❌ Служебный API — обратная совместимость не гарантируется
Параметры = ОбновлениеИнформационнойБазыСлужебный.ПараметрыОбновления();
Параметры.КакойТоНовыйПараметр = Истина;  // сломается при обновлении БСП
```

```bsl
// ✅ Стабильный API — `ВерсияИБ`, `УстановитьВерсиюИБ`, `ВерсииПодсистем`
Версии = ОбновлениеИнформационнойБазы.ВерсииПодсистем();
```

### ❌ Игнорировать результат `ИсправленияИзменены` перед обновлением

```bsl
// ❌ Обновление запускается без очистки устаревших патчей —
// может привести к накоплению «мёртвых» исправлений и ошибкам совместимости
ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы();
```

```bsl
// ✅ Всегда сначала патчи
ОбновлениеКонфигурации.ИсправленияИзменены();
ОбновлениеИнформационнойБазы.ВыполнитьОбновлениеИнформационнойБазы();
```

## How to explore deeper

### Какие общие модули изучить

- `ОбновлениеИнформационнойБазы` — основной стабильный API (Сервер + Внешнее соединение + Толстый клиент).
- `ОбновлениеИнформационнойБазыКлиент` — клиентские формы и индикация хода обновления.
- `ОбновлениеИнформационнойБазыГлобальный` — глобальный крючок `ПроверитьСтатусОтложенногоОбновления`.
- `ОбновлениеИнформационнойБазыВызовСервера` — серверный вызов `ВыполнитьОбновлениеИнформационнойБазы` без контекста формы.
- `ОбновлениеИнформационнойБазыПереопределяемый` — крючки для прикладной конфигурации (`ПередОбновлениемИнформационнойБазы`, `ПослеОбновленияИнформационнойБазы`, `ПриОпределенииНастроек`, `ПриОпределенииПроверок`).
- `ОбновлениеИнформационнойБазыКлиентПереопределяемый` — клиентские крючки (`ПриОпределенииВозможностиОбновления`, `ПриНажатииНаГиперссылкуВДокументеОписанияОбновлений`).
- ⚠️ `ОбновлениеИнформационнойБазыСлужебный` — служебный API (внутренняя итерация обновления, фоновое обновление, блокировка ИБ).
- ⚠️ `ОбновлениеИнформационнойБазыСлужебныйВызовСервера` — служебный серверный вызов.
- ⚠️ `ОбновлениеИнформационнойБазыСлужебныйПовтИсп` — служебный кэш (`МинимальнаяВерсияИБ`, `ОчередьОтложенногоОбработчикаОбновления`).
- `ОбновлениеКонфигурации` — стабильный API интерактивного обновления и патчей (Сервер).
- `ОбновлениеКонфигурацииКлиент` — клиентский API (`ПоддерживаетсяУстановкаОбновлений`, `ПоказатьПоискИУстановкуОбновлений`).
- `ОбновлениеКонфигурацииГлобальный` — глобальный обработчик ожидания.
- `ОбновлениеКонфигурацииВызовСервера` — серверные вызовы для скриптов обновления.

### Какие объекты метаданных посмотреть

- **Регистр сведений `ВерсииПодсистем`** — хранит версии подсистем и основной конфигурации. Измерения: `ИмяПодсистемы`, `Версия`. Запись идёт через `УстановитьВерсиюИБ`.
- **Регистр сведений `ОбновляемыеОбъекты`** — регистрирует ссылки / наборы, подлежащие отложенной обработке. Измерения: `ИмяОбработчика`, `КлючОбъекта`. Заполняется в `ПроцедураЗаполненияДанныхОбновления` отложенного обработчика.
- **Регистр сведений `ОбработчикиОбновления`** — таблица обработчиков, формируемая в `ПриДобавленииОбработчиковОбновления`. Измерения: `ИмяОбработчика`, `ИмяБиблиотеки`, `Версия`, `Статус`.
- **План обмена `ОбновлениеИнформационнойБазы`** — основной план обмена для распределённых ИБ. Регистрация изменений из обработчика обновления идёт через параметр `РегистрироватьНаУзлахПлановОбмена` обёрток `ЗаписатьОбъект` / `ЗаписатьДанные`.
- **Обработка `УстановкаОбновлений`** — интерактивная установка обновлений конфигурации. Открывается через `ОбновлениеКонфигурацииКлиент.ПоказатьПоискИУстановкуОбновлений`.
- **Общая форма `УстановленныеИсправления`** — список установленных патчей. Открывается через `ОбновлениеКонфигурацииКлиент.ПоказатьУстановленныеИсправления`.
- **Перечисление `РежимыВыполненияОбработчиков`** — допустимые значения: `Монопольно`, `Оперативно`, `Отложенно`, `Параллельно`. Используется в колонке `РежимВыполнения` таблицы обработчиков.
- **Перечисление `СтатусыОбработчиковОбновления`** — статусы обработчика (`Выполнен`, `НеВыполнен`, `Выполняется`).
- **Перечисление `ПорядокОбработчиковОбновления`** — для режима `Параллельно`.
- **Подписки на события** `ОбновлениеВерсииИБПередУдалениемСсылочногоОбъекта` (служебная подписка модуля `ОбновлениеИнформационнойБазыСлужебный`) — контролирует удаление объектов до завершения обновления.

### Grep-шаблоны

```text
# Найти все экспортные методы основного модуля (для оценки объёма API)
^(Функция|Процедура) [А-Я][А-Яа-яA-Za-z_]+\(.*\) Экспорт

# Найти стабильный API внутри модуля
^#Область ПрограммныйИнтерфейс

# Найти служебный API (⚠️ — обратная совместимость не гарантируется)
^#Область СлужебныйПрограммныйИнтерфейс

# Найти реализации крючков в прикладных модулях обработчиков
^Процедура ПриДобавленииОбработчиковОбновления\(.*\) Экспорт

# Найти реализации переопределяемых крючков в прикладной конфигурации
^Процедура (ПередОбновлениемИнформационнойБазы|ПослеОбновленияИнформационнойБазы|ПриОпределенииНастроек|ПриОпределенииПроверок)\(.*\) Экспорт

# Проверить существование метода в служебном модуле (⚠️)
^(Функция|Процедура) <ИмяМетода>\(.*\) Экспорт
```

### На что обратить внимание

- **В формах объектов**: реквизит `АвтоОтметкаНезаполненного` для полей, которые могут быть заблокированы отложенным обработчиком. Стандартная функция проверки блокировки — `ДанныеОбновленыНаНовуюВерсиюПрограммы` через подсистему `ПроверкаЛегальностиПолученияОбновления` или через `ПриОпределенииПроверок` в переопределяемом модуле.
- **В командном интерфейсе**: форма `УстановкаОбновлений` (открывает поиск и установку обновлений), форма `УстановленныеИсправления` (список патчей).
- **В регламентных заданиях**: задание `ОтложенноеОбновление` (выполняется фоново, обрабатывает очередь отложенных обработчиков). Создаётся автоматически при подключении подсистемы; настройки — через `РегламентныеЗаданияСервер`.
- **В модуле приложения**: при `УстановкаПараметровСеанса` подсистема заполняет параметр `ОбновлениеИнформационнойБазы` (внутренний кэш). Не обращайтесь к нему напрямую — используйте экспортные методы.
- **В планах обмена**: для `РИБ` обновление данных идёт через `ПриОтправкеДанныхПодчиненному` / `ПриОтправкеДанныхГлавному` в `ОбновлениеИнформационнойБазыСлужебный` (⚠️).
- **В модуле формы констант** с настройками обновления: используется `ОбновлениеКонфигурации.НастройкиОбновленияКонфигурации` для получения текущих настроек и `СохранитьНастройкиОбновленияКонфигурации` для записи.
