Всем привет!
Я senior разработчик 1С, прошел много собеседований и почти на каждом спрашивают про транзакции. В процессе подготовки я понял что нормального сжатого материала по этой теме нет. Если вы решите погуглить то вам попадется куча обрывочных довольно нетривиальных статей и нужно потратить много времени разобраться в этом. Посему делюсь выжимкой знаний про то, что спрашивают на собесах и ответами на них.
P.S.: Здесь мы не будем разбирать другие вопросы, которые тоже очень часто любят спрашивать про транзакции — это ACID и уровни изоляции транзакций.
-
Что такое транзакция в общем?
Это принцип — выполнится «все или ничего». К примеру, в 1С это операции между конструкциями
НачатьТранзакцию();//ЗафиксироватьТранзакцию(); -
Явные / Неявные транзакции:
Явные — через НачатьТранзакцию(), ЗафиксироватьТранзакцию()
Неявные — к примеру, в модуле объекта справочника ПриЗаписи() -
Бывают ли вложенные транзакции?
На уровне СУБД нет, на уровне кода 1С можно писать сколько угодно раз НачатьТранзакцию() (счетчик вложенности увеличивается) а потом столько же раз ЗафиксироватьТранзакцию() (счетчик вложенности уменьшается), НО на уровне СУБД при этом будет создана только одна транзакция и она будет завершена когда последняя ЗафиксироватьТранзакцию() (счетчик вложенности = 0) отработает.
-
Что такое сломанная транзакция?
Состояние, когда СУБД уже откатила транзакцию из‑за ошибки, но код приложения 1С продолжает выполняться, и любые дальнейшие обращения к БД приводят к ошибке «в данной транзакции уже происходили ошибки».
Из кода 1С мы никак не можем понять что транзакция сломана, но есть костыль:

-
Способы получения сломанной транзакции?
Вариант 1: Ошибка при операции в базе данных ! Ошибка может быть и во вложенной неявной транзакции. К примеру, в модуле объекта справочника, который мы пытаемся записать в попытке.
Вариант 2: через ОтменитьТранзакцию() ! ОтменитьТранзакцию() это так же установка флага Отказ в Истина, допустим, при записи справочника.
-
Когда мы НЕ получим сломанную транзакцию?
Когда ошибка в Попытке/Исключении не будет связана с обращением к СУБД

-
Стандарты разработки по написанию транзакций:
НачатьТранзакцию();Попытка // блокировки, чтение, запись // … ЗафиксироватьТранзакцию();Исключение ОтменитьТранзакцию(); ВызватьИсключение; // если есть внешняя транзакцияКонецПопыткиПолный код обработки:
Процедура СломаемТранзакциюВариант1() НачатьТранзакцию(); Попытка Запрос = Новый Запрос; Запрос.Текст = "Выбрать 1/0"; Запрос.Выполнить(); Исключение КонецПопытки; Сообщить(ЭтаТранзакцияСломана()); //Да! ЗафиксироватьТранзакцию(); КонецПроцедурыПроцедура СломаемТранзакциюВариант2() НачатьТранзакцию(); Попытка НачатьТранзакцию(); ОтменитьТранзакцию(); Исключение КонецПопытки; Сообщить(ЭтаТранзакцияСломана()); //Да! ЗафиксироватьТранзакцию(); КонецПроцедурыПроцедура НеСломаемТранзакцию() НачатьТранзакцию(); Попытка а = Новый Структура; б = а.НовоеПоле; Исключение КонецПопытки; Сообщить(ЭтаТранзакцияСломана()); //Нет! ЗафиксироватьТранзакцию(); КонецПроцедурыФункция ЭтаТранзакцияСломана() Попытка Запрос = Новый Запрос; Запрос.Текст = "Выбрать 1"; Запрос.Выполнить(); Возврат Ложь; Исключение Возврат Истина; КонецПопытки; КонецФункции
ссылка на оригинал статьи https://habr.com/ru/articles/1028326/