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

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

Транзакции в 1С: для чего нужны и как их использовать

Что такое транзакции в 1С, зачем они нужны, как работают НачатьТранзакцию и ЗафиксироватьТранзакцию, типичные ошибки и правила безопасной записи данных.

Транзакция в 1С — это механизм, который гарантирует целостность данных при выполнении группы связанных операций. Если в процессе проведения документа, загрузки данных или обмена что-то идёт не так, транзакция позволяет отменить все изменения целиком, а не оставлять базу в половинчатом состоянии. Без этого механизма частично записанные документы, «оборванные» остатки и расхождения в регистрах были бы обычным делом.

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

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

Что такое транзакция и какой принцип она реализует

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

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

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

Для чего транзакции нужны на практике

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

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

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

Проведение документаАвтоматическая транзакция

Платформа сама оборачивает запись документа и его движения

Запись элемента справочникаАвтоматическая транзакция

Объект и связанные служебные записи сохраняются атомарно

Обмен даннымиТранзакции в механизмах обмена

Пакеты сообщений применяются целиком или откатываются

Программная обработкаЯвные транзакции в коде

Разработчик управляет границами через методы платформы

Как транзакции устроены в платформе 1С

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

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

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

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

Как правильно использовать явные транзакции в коде

Главное правило: каждая открытая транзакция должна быть гарантированно закрыта — зафиксирована или отменена. Стандартный приём — оборачивать тело в конструкцию Попытка...Исключение...КонецПопытки, где ветка исключения всегда содержит ОтменитьТранзакцию(). Если этого не сделать, транзакция останется «висеть» до завершения вызова сервера, что удерживает блокировки и мешает другим пользователям.

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

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

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

Блокировки, конкурентный доступ и типичные проблемы

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

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

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

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

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

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

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

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

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

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

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

Состояние данных после ошибки
Норма

Ни один объект из группы не записан

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

Часть объектов записана, часть — нет

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

Есть запись об ошибке с описанием причины

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

Ошибок нет, хотя операция не выполнилась

Работа других пользователей во время обработки
Норма

Паузы кратковременны, конфликты редки

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

Массовые ошибки конфликта блокировок

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

Обработка выполняется без дублей и ошибок уникальности

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

Появляются дубли или ошибки «запись уже существует»

Если проверка выявляет частично записанные данные, значит, операции выполнялись вне общей транзакции или границы транзакции выбраны неверно. Такой код нужно пересмотреть до запуска в рабочей базе: исправлять рассогласованные данные вручную заметно дороже, чем один раз выстроить правильные границы.

Когда явные транзакции не нужны

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

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

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

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

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

Итог

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

Транзакция гарантирует принцип «всё или ничего» для группы операций. Стандартные записи платформа защищает сама; явные транзакции нужны для связанных наборов изменений. Держите транзакции короткими, всегда отменяйте их в обработчике ошибок, не размещайте внутри диалоги и фиксируйте ошибки в журнале регистрации.

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

Что произойдёт с данными, если во время проведения документа отключится электричество?

Незавершённая транзакция будет автоматически откачена СУБД при восстановлении работы. Документ останется в исходном состоянии — как будто попытки проведения не было. Частично записанных движений не появится, потребуется просто повторить проведение.

Чем отличается ЗафиксироватьТранзакцию от ОтменитьТранзакцию?

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

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

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

Можно ли вкладывать транзакции друг в друга?

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

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

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

Как найти виновника длительных блокировок в рабочей базе?

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