В 1С вложенных транзакций не бывает. Вы можете написать сколь угодно большую вложенность
НачатьТранзакцию() - счётчик 1
НачатьТранзакцию() - счётчик 2
НачатьТранзакцию() - счётчик 3
Всё это будет одна транзакция. На сервере приложений будет лишь увеличен счетчик количества транзакций. Фактически транзакция завершиться, когда вы напишите
ЗафиксироватьТранзацию() - счётчик 2
ЗафиксироватьТранзацию() - счётчик 1
ЗафиксироватьТранзацию() - счётчик 0 - транзакция фактически будет зафиксирована
В процессе работы, транзакция может завершиться и ошибкой. Причины могут быть самые разные. Поэтому работу с транзакциями нужно оборачивать в попытку. Важно НачатьТранзакцию() должно быть сразу перед Попыткой.
НачатьТранзакцию();
Попытка
ДокументОбъект.Записать()
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ВызватьИсключение;
КонецПопытки;
ВызватьИсключение - рекомендуется вызывать после отмены транзакции, чтобы в случае если наша транзакция является внутренней, пробросить исключение на внешнюю транзакцию, и не дать ей зафиксироваться. В противном случае если этого не сделать, когда мы выйдем на внешнюю транзакцию и попробуем обратиться к базе данных (записать или прочитать), то получим очень веселую ошибку "В данной транзакции уже происходили ошибки". Эта ошибка которую очень сложно отловить, поэтому лучше сразу работать с транзакциями правильно, т.к эта ошибка 100% результат некорректной работы с транзакциями со стороны разработчика.
Ошибки в транзакциях бывают восстановимые и невосстановимые. Восстановимые ошибки - это такие ошибки, которые не влияют на работу базы данных, поэтому могут быть обработаны в исключительной ситуации, и транзакцию даже можно будет зафиксировать.
Как вы думаете будет ли записан элемент ?
НачатьТранзакцию();
Попытка
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Новый";
НовыйЭлемент.Записать();
ВызватьИсключение "Какая-то ошибка";
ЗафиксироватьТранзакцию();
Исключение
КонецПопытки;
ЗафиксироватьТранзакцию();
Да, элемент будет записан. Но так делать не следует, это демонстрационный пример. Так как исключение не связано с базой данных, мы можем дальше продолжить работу с транзакцией. В случае, если в строке НовыйЭлемент.Записать() - у нас выпадет исключение, например перед записью сработала проверка, и мы установили "Отказ = Истина", то это будет расценено как ошибка при работе с базой данных, и соответственно будет являться "невосстановимой ошибкой". Транзакция будет помечена испорченной, и единственное, что мы должны сделать это отменить ее. Если мы дальше попробуем обратиться к базе данных, даже банально прочитать представление ссылки, то получим уже знакомую ошибку "В данной транзакции уже происходили ошибки".
Ну и на последок, транзакции никак не влияют на значения переменных в оперативной памяти.
НоменклатураОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НоменклатураОбъект.Наименование = "Тест1";
НоменклатураОбъект.Записать();
НачатьТранзакцию();
НоменклатураОбъект.Наименование = "Тест2";
НоменклатураОбъект.Записать();
ОтменитьТранзакцию();
Что выведут методы ?
Сообщить(НоменклатураОбъект.Наименование);
Сообщить(НоменклатураОбъект.Ссылка.Наименование);
В нижеприведенном примере НоменклатураОбъект - объект в оперативной памяти. И после отмены транзакции данные в базу данных записаны не будут, но "Тест2" будет сохранен в оперативной памяти, и Сообщить(НоменклатураОбъект.Наименование); выведет "Тест2", а Сообщить(НоменклатураОбъект.Ссылка.Наименование); выведет "Тест1".
Отличная статья Андрея Овсянкина про транзакции на хабре.
