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

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

Что значит транзакция в 1С и как она работает

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

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

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

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

Как работает принцип «всё или ничего»

У транзакции есть два возможных исхода. Фиксация (commit) — все изменения, накопленные с момента начала транзакции, окончательно записываются в базу и становятся видны другим пользователям. Откат (rollback) — все изменения отменяются, база остаётся в том состоянии, в котором была до начала транзакции. Промежуточного состояния «часть записалась, часть нет» не существует.

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

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

Где транзакции встречаются в повседневной работе

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

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

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

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

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

НачатьТранзакцию();

Попытка

Для Каждого Строка Из Товары Цикл

СписатьОстаток(Строка.Номенклатура, Строка.Количество);

КонецЦикла;

СформироватьРасчеты(Документ);

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение ОписаниеОшибки();

КонецПопытки;

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

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

Блокировки и конфликты транзакций

Когда транзакция изменяет данные, она ставит на них блокировку, чтобы другой сеанс не смог одновременно изменить те же записи. Если второй пользователь пытается записать заблокированный объект, он ждёт освобождения, а по истечении таймаута получает ошибку конфликта блокировок. В файловых базах блокировки грубее — часто на уровне целой таблицы, поэтому конфликты возникают чаще; в клиент-серверном варианте на СУБД блокировки построчные и конкуренция ниже.

Отдельная проблема — взаимоблокировка (deadlock): сеанс А держит ресурс 1 и ждёт ресурс 2, а сеанс Б держит ресурс 2 и ждёт ресурс 1. СУБД обнаруживает такую ситуацию и принудительно откатывает одну из транзакций, выбирая «жертву». Пользователь при этом видит ошибку, и операцию нужно повторить.

Конфликт блокировокДва сеанса пишут в одни данные

Повторить операцию; если повторяется — искать длинные транзакции в коде

Превышено время ожиданияОбъект долго заблокирован другим сеансом

Проверить активные сеансы и регламентные задания

ВзаимоблокировкаСеансы заблокировали друг друга

Унифицировать порядок записи объектов в коде

Ошибка СУБД при фиксацииНарушение на уровне базы данных

Смотреть технологический журнал и логи СУБД

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

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

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

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

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

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

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

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

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

При исключении в базе нет частичных изменений

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

Записалась часть документов или движений

Активные сеансы
Норма

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

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

Блокировка висит после завершения обработки

Технологический журнал
Норма

Нет событий TDEADLOCK и TTIMEOUT

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

Регулярные взаимоблокировки и таймауты

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

Операция идемпотентна или корректно догружает остаток

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

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

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

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

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

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

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

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

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

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

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

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

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

Незафиксированная транзакция откатывается СУБД автоматически при разрыве соединения. Данные остаются в согласованном состоянии, но пользователю нужно повторить операцию — платформа не восстановит её сама.

Влияет ли режим управляемых блокировок на транзакции?

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

Итог

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

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