При работе с объектами, предназначенными для модификации данных, хранящихся в базе данных, следует учитывать некоторые особенности их работы в транзакциях.
В общем виде транзакция управляет только изменениями, вносимыми в базу данных, и не влияет на изменение значений в памяти. То есть, если после начала транзакции в модуле выполнялась запись информации в базу данных, и изменялись какие-либо переменные или свойства объектов, то при отмене транзакции изменения в базе данных будут отменены, а изменения в переменных модулей и свойствах объектов расположенных в памяти отменены не будут.
Это обстоятельство следует учитывать при разработке модулей выполняющих последовательность некоторых действий в рамках транзакции.
Например, если в модуле выполнить изменение свойств объекта, записать его, а потом отменить транзакцию, то значение измененных свойств в базе данных будет соответствовать значению до начала транзакции, а значение свойств в памяти будет включать выполненные изменения.
Приведем пример:
Копировать в буфер обменаНоменклатураОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НоменклатураОбъект.Наименование = "Тест1";
НоменклатураОбъект.Записать();
НачатьТранзакцию();
НоменклатураОбъект.Наименование = "Тест2";
НоменклатураОбъект.Записать();
ОтменитьТранзакцию();
Сообщить(НоменклатураОбъект.Наименование); //Тест2
Сообщить(НоменклатураОбъект.Ссылка.Наименование); //Тест1
Как видно из примера, при обращении к свойству объекта в памяти мы получаем измененное свойство, а при обращении к данным объекта в базе данных (через ссылку) получаем значение свойства на момент начала транзакции.
Однако исключение делается для ссылки объекта. После отмены транзакции значение ссылки нового объекта, присвоенное в ходе транзакции очищается.
Приведем пример:
Копировать в буфер обменаПерем Ссылка;
НачатьТранзакцию();
НоменклатураОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НоменклатураОбъект.Записать();
Ссылка = НоменклатураОбъект.Ссылка;
ОтменитьТранзакцию();
Сообщить(НоменклатураОбъект.Ссылка = Справочники.Номенклатура.ПустаяСсылка()); //истина
Сообщить(Ссылка); // <Объект не найден> (1:9e4b00055d4c7bcf11d934028f79e857)
Таким образом, если в ходе транзакции запомнить ссылку создаваемого объекта, то она будет указывать на несуществующий объект базы данных, а само свойство будет равняться пустой ссылке.
Еще одной особенностью является очистка автоматически присвоенного при записи кода (номера) объекта при отмене транзакции, если объект не был создан в транзакции.
Приведем пример:
Копировать в буфер обменаПерем Код;
НоменклатураОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НачатьТранзакцию();
НоменклатураОбъект.Записать();
Код = НоменклатураОбъект.Код;
ОтменитьТранзакцию();
Сообщить(НоменклатураОбъект.Код); //
Сообщить(Код); //4568
Особенностью работы документов в транзакциях является восстановление при отмене транзакции признака проведенности документа.
Приведем пример:
Копировать в буфер обменаПерем Проведен;
НачатьТранзакцию();
ПриходнаяНакладнаяОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
ПриходнаяНакладнаяОбъект.Дата = ТекущаяДата();
ПриходнаяНакладнаяОбъект.Записать(РежимЗаписиДокумента.Проведение);
Проведен = ПриходнаяНакладнаяОбъект.Проведен;
ОтменитьТранзакцию();
Сообщить(ПриходнаяНакладнаяОбъект.Проведен); //ложь
Сообщить(Проведен); //истина
В описанных особенностях следует учитывать то, что, как и отмена изменений в базе данных, восстановление значений указанных свойств в памяти происходит в момент отмены транзакции. При этом отмена транзакции может произойти совсем не в той же самой процедуре, в которой выполняется запись, так как эта процедура может быть вызвана из другой процедуры, в которой начинается и отменяется транзакция. Соответственно алгоритм, выполняемый после записи объекта, не может исходить из того, что выполненная операция записи уже не может быть отменена.