Всем привет!

Я senior разработчик 1С, прошел много собеседований и почти на каждом спрашивают про транзакции. В процессе подготовки я понял что нормального сжатого материала по этой теме нет. Если вы решите погуглить то вам попадется куча обрывочных довольно нетривиальных статей и нужно потратить много времени разобраться в этом. Посему делюсь выжимкой знаний про то, что спрашивают на собесах и ответами на них.

P.S.: Здесь мы не будем разбирать другие вопросы, которые тоже очень часто любят спрашивать про транзакции - это ACID и уровни изоляции транзакций.

  1. Что такое транзакция в общем?

    Это принцип — выполнится «все или ничего». К примеру, в 1С это операции между конструкциями

    НачатьТранзакцию();
    //
    ЗафиксироватьТранзакцию();
  2. Явные / Неявные транзакции:

    Явные — через НачатьТранзакцию(), ЗафиксироватьТранзакцию()
    Неявные — к примеру, в модуле объекта справочника ПриЗаписи()

  3. Бывают ли вложенные транзакции?

    На уровне СУБД нет, на уровне кода 1С можно писать сколько угодно раз НачатьТранзакцию() (счетчик вложенности увеличивается) а потом столько же раз ЗафиксироватьТранзакцию() (счетчик вложенности уменьшается), НО на уровне СУБД при этом будет создана только одна транзакция и она будет завершена когда последняя ЗафиксироватьТранзакцию() (счетчик вложенности = 0) отработает.

  4. Что такое сломанная транзакция?

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

    Из кода 1С мы никак не можем понять что транзакция сломана, но есть костыль:

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

    Вариант 1: Ошибка при операции в базе данных
    Вариант 1: Ошибка при операции в базе данных












    ! Ошибка может быть и во вложенной неявной транзакции. К примеру, в модуле объекта справочника, который мы пытаемся записать в попытке.

    Вариант 2: через ОтменитьТранзакцию()
    Вариант 2: через ОтменитьТранзакцию()













    ! ОтменитьТранзакцию() это так же установка флага Отказ в Истина, допустим, при записи справочника.

  6. Когда мы НЕ получим сломанную транзакцию?

    Когда ошибка в Попытке/Исключении не будет связана с обращением к СУБД











  7. Стандарты разработки по написанию транзакций:

    НачатьТранзакцию();
    Попытка
         // блокировки, чтение, запись 
         // … 
         ЗафиксироватьТранзакцию();
    Исключение
         ОтменитьТранзакцию();
         ВызватьИсключение; // если есть внешняя транзакция
    КонецПопытки

    Полный код обработки:

Процедура СломаемТранзакциюВариант1()
  
  НачатьТранзакцию();
  
  Попытка
    Запрос = Новый Запрос;
    Запрос.Текст = "Выбрать 1/0";
    Запрос.Выполнить();
  Исключение
  КонецПопытки;
  
  Сообщить(ЭтаТранзакцияСломана()); //Да!
  
  ЗафиксироватьТранзакцию();
  
КонецПроцедуры

Процедура СломаемТранзакциюВариант2()
  
  НачатьТранзакцию();
  
  Попытка
    НачатьТранзакцию();
    ОтменитьТранзакцию();
  Исключение
  КонецПопытки;
  
  Сообщить(ЭтаТранзакцияСломана()); //Да!
  
  ЗафиксироватьТранзакцию();
  
КонецПроцедуры

Процедура НеСломаемТранзакцию()
  
  НачатьТранзакцию();
  
  Попытка
    а = Новый Структура;
    б = а.НовоеПоле;
  Исключение
  КонецПопытки;
  
  Сообщить(ЭтаТранзакцияСломана()); //Нет!
    
  ЗафиксироватьТранзакцию();
  
КонецПроцедуры


Функция ЭтаТранзакцияСломана()

  Попытка
    Запрос = Новый Запрос;
    Запрос.Текст = "Выбрать 1";
    Запрос.Выполнить();
    Возврат Ложь;
  Исключение
    Возврат Истина;
  КонецПопытки;
  
КонецФункции

Комментарии (0)