К статье
Практический материал

Разработка и Конфигурация · 11 мин

Что такое транзакция и для чего она используется в 1С

Что такое транзакция в 1С, как работают BeginTransaction и CommitTransaction, где применяются транзакции, типичные ошибки и правила безопасной работы с данными.

Транзакция — это способ объединить несколько операций с данными в одну неделимую единицу: либо выполняются все изменения целиком, либо не выполняется ни одно из них. В 1С транзакции защищают базу от ситуаций, когда документ провёлся наполовину, справочник записался, а связанные с ним регистры — нет, и учёт «разъехался».

Простой пример: при проведении документа «Реализация товаров» программа должна списать товар со склада, сформировать проводки и обновить взаиморасчёты с покупателем. Если на середине операции произойдёт сбой, без транзакции часть данных запишется, а часть — нет. Транзакция гарантирует, что при ошибке база вернётся в исходное состояние, как будто проведения вообще не было.

Механизм транзакций работает и на уровне платформы 1С, и на уровне СУБД (MS SQL Server, PostgreSQL и других). Разработчик в явном виде управляет транзакциями через встроенный язык, а типовые операции — запись документа, проведение, обмен данными — платформа оборачивает в транзакции автоматически.

Как устроена транзакция: основные понятия

Транзакция имеет три ключевых состояния: начало, фиксация и откат. Начало открывает «контейнер» для изменений. Фиксация (commit) подтверждает, что все операции выполнены успешно, и делает изменения постоянными. Откат (rollback) отменяет всё, что было сделано с момента начала транзакции, и возвращает данные в исходное вид.

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

Важно различать транзакцию платформы и транзакцию СУБД. Когда вы вызываете методы транзакций во встроенном языке, платформа транслирует их в команды сервера баз данных. Фактические блокировки, журналы и откаты выполняет именно СУБД, а 1С управляет логикой: что именно входит в транзакцию и когда её завершать.

Где 1С использует транзакции автоматически

Большинство транзакций в 1С происходит без участия разработчика. Платформа сама оборачивает в транзакцию запись и проведение документов: если проведение прерывается ошибкой (например, не хватило товара на складе), движения по регистрам откатываются, и документ остаётся непроведённым, а не «наполовину проведённым».

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

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

Явное управление транзакциями во встроенном языке

Для ручного управления в 1С есть три метода: НачатьТранзакцию(), ЗафиксироватьТранзакцию() и ОтменитьТранзакцию(). Типовой шаблон выглядит так: транзакция открывается, внутри выполняются записи объектов, при успехе транзакция фиксируется, а при любой ошибке в блоке Попытка...Исключение — отменяется.

Порядок действий при явной транзакции
  1. 1
    Вызовите НачатьТранзакцию() перед первой изменяющей операцией
  2. 2
    Выполните все записи объектов внутри блока Попытка
  3. 3
    При успешном завершении вызовите ЗафиксироватьТранзакцию()
  4. 4
    В блоке Исключение вызовите ОтменитьТранзакцию() и зафиксируйте ошибку в журнале регистрации
  5. 5
    Проверьте в тестовой базе, что при искусственной ошибке данные откатываются полностью

Пример ситуации: обработка загружает заказы из файла и для каждого создаёт документ, контрагента и договор. Если все три объекта связаны, разумно объединить их запись в одну транзакцию на каждый заказ. Тогда при повреждённой строке файла не останется «висячего» контрагента без документа.

bsl
НачатьТранзакцию();
Попытка
    ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
    КонтрагентОбъект.Записать();
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ЗаписьЖурналаРегистрации("Загрузка", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;

Обратите внимание: транзакции в 1С нельзя вкладывать друг в друга на уровне кода — повторный вызов НачатьТранзакцию() внутри уже открытой транзакции приведёт к ошибке. Если процедура может вызываться и внутри, и снаружи транзакции, используйте функцию ТранзакцияАктивна() для проверки текущего состояния.

Транзакции и блокировки: почему возникают конфликты

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

В управляемом режиме 1С по умолчанию используются управляемые блокировки: они накладываются по конкретным измерениям данных (например, по складу и номенклатуре), а не на всю таблицу целиком. Это резко снижает число конфликтов по сравнению со старым автоматическим режимом, но требует от разработчика понимания, какие данные реально блокируются.

Признак проблем с блокировками — ошибки вида «Конфликт блокировок при выполнении транзакции» и «Превышено время ожидания» в журнале регистрации. Если они появляются регулярно, нужно анализировать, какие операции выполняются слишком долго внутри транзакций, и пересматривать порядок обращения к данным.

Типичные ошибки при работе с транзакциями

Типичные ошибки
01
Открытие транзакции и отсутствие ОтменитьТранзакцию() в блоке Исключение — при ошибке транзакция зависает и держит блокировки до конца сеанса
02
Вызов интерактивных действий (Вопрос, Предупреждение, открытие формы) внутри транзакции — блокировка удерживается, пока пользователь думает над ответом
03
Одна транзакция на всю массовую обработку из тысяч объектов — долгие блокировки, рост журнала СУБД и риск таймаутов у других пользователей
04
Попытка вложить транзакции без проверки ТранзакцияАктивна() — ошибка выполнения в момент вызова из другого кода
05
Фиксация транзакции до завершения всех связанных записей — часть данных записывается отдельно, и логическая целостность теряется

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

Ещё одна ловушка — обращение к внешним системам (HTTP-запросы, веб-сервисы) внутри транзакции. Внешний сервис может отвечать секунды или минуты, и всё это время блокировки удерживаются. Правильный подход: сначала получить данные извне, потом открыть транзакцию и быстро записать результат.

Как проверить, что транзакционная логика работает правильно

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

Контрольные точки

Как проверить результат

Данные после успешного выполнения
Норма

Записаны все объекты, движения согласованы между собой

Тревожный признак

Часть объектов есть, часть отсутствует или не проведена

Данные после искусственной ошибки
Норма

Новых записей нет вообще, справочники и регистры в исходном состоянии

Тревожный признак

Остались «висячие» записи без связанных документов

Журнал регистрации
Норма

Ошибка зафиксирована с понятным описанием, нет зависших транзакций

Тревожный признак

Ошибки конфликта блокировок повторяются, транзакции не завершаются

Повторный запуск обработки после сбоя
Норма

Обработка выполняется корректно, дублей не создаётся

Тревожный признак

Появляются дубли объектов или ошибки уникальности

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

Когда транзакции нужны, а когда можно обойтись без них

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

Маршрут решения

Как выбрать действие

Записывается один документ или элемент справочника штатным методомНе открывайте транзакцию вручную — платформа сделает это автоматически
Операция изменяет несколько связанных объектов, и частичная запись недопустимаОбъедините записи в одну явную транзакцию с обработкой исключений
Выполняется массовая загрузка тысяч объектовИспользуйте транзакцию на каждый логический пакет, а не на весь объём
Внутри операции есть обращение к внешнему сервису или ожидание пользователяВынесите эти действия за пределы транзакции

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

Итог

Что важно запомнить

Транзакция обеспечивает принцип «всё или ничего»: при ошибке данные полностью откатываются. Типовые операции 1С транзакционны автоматически; вручную транзакции открывают только для многообъектных операций, всегда с отменой в блоке Исключение и без длительных действий внутри.

Частые вопросы о транзакциях в 1С

Чем транзакция отличается от обычной записи документа?

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

Можно ли отменить транзакцию после её фиксации?

Нет. После вызова ЗафиксироватьТранзакцию() изменения становятся постоянными. Исправить данные можно только новой операцией: сторнированием документа, корректировкой или удалением записей штатными средствами.

Почему появляется ошибка «Конфликт блокировок при выполнении транзакции»?

Два сеанса одновременно пытаются изменить одни и те же данные, и один ждёт освобождения блокировки дольше допустимого времени. Обычно помогает повтор операции; если ошибка систематическая — нужно искать длительные транзакции и оптимизировать порядок обращения к данным.

Работают ли транзакции в файловом варианте 1С?

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

Что будет, если сеанс завершился, не закрыв транзакцию?

При разрыве соединения или аварийном завершении сеанса СУБД автоматически откатывает незавершённую транзакцию. Данные вернутся в состояние на момент её начала, поэтому «висячих» изменений после обрыва не остаётся.

Нужно ли открывать транзакцию при записи одного элемента справочника?

Нет, в этом нет смысла: метод Записать() уже выполняется атомарно. Явная транзакция оправдана только тогда, когда вместе со справочником должны записаться другие связанные объекты и их рассогласование недопустимо.