Особенности работы объектов при отмене транзакции

При работе с объектами, предназначенными для модификации данных, хранящихся в базе данных, следует учитывать некоторые особенности их работы в транзакциях.

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

Это обстоятельство следует учитывать при разработке модулей выполняющих последовательность некоторых действий в рамках транзакции.

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

Приведем пример:

Копировать в буфер обмена

НоменклатураОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НоменклатураОбъект.Наименование = "Тест1";
НоменклатураОбъект.Записать();
НачатьТранзакцию();
НоменклатураОбъект.Наименование = "Тест2";
НоменклатураОбъект.Записать();
ОтменитьТранзакцию();
Сообщить(НоменклатураОбъект.Наименование);  //Тест2
Сообщить(НоменклатураОбъект.Ссылка.Наименование); //Тест1

Как видно из примера, при обращении к свойству объекта в памяти мы получаем измененное свойство, а при обращении к данным объекта в базе данных (через ссылку) получаем значение свойства на момент начала транзакции.

Однако исключение делается для ссылки объекта. После отмены транзакции значение ссылки нового объекта, присвоенное в ходе транзакции очищается.

Приведем пример:

Копировать в буфер обмена

Перем Ссылка;
НачатьТранзакцию();
НоменклатураОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НоменклатураОбъект.Записать();
Ссылка = НоменклатураОбъект.Ссылка;
ОтменитьТранзакцию();
Сообщить(НоменклатураОбъект.Ссылка = Справочники.Номенклатура.ПустаяСсылка()); //истина
Сообщить(Ссылка); // <Объект не найден> (1:9e4b00055d4c7bcf11d934028f79e857)

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

Еще одной особенностью является очистка автоматически присвоенного при записи кода (номера) объекта при отмене транзакции, если объект не был создан в транзакции.

Приведем пример:

Копировать в буфер обмена

Перем Код;
НоменклатураОбъект = Справочники.Номенклатура.СоздатьЭлемент();
НачатьТранзакцию();
НоменклатураОбъект.Записать();
Код = НоменклатураОбъект.Код;
ОтменитьТранзакцию();
Сообщить(НоменклатураОбъект.Код);  //
Сообщить(Код);  //4568

Особенностью работы документов в транзакциях является восстановление при отмене транзакции признака проведенности документа.

Приведем пример:

Копировать в буфер обмена

Перем Проведен;
НачатьТранзакцию();
ПриходнаяНакладнаяОбъект = Документы.ПриходнаяНакладная.СоздатьДокумент();
ПриходнаяНакладнаяОбъект.Дата = ТекущаяДата();
ПриходнаяНакладнаяОбъект.Записать(РежимЗаписиДокумента.Проведение);
Проведен = ПриходнаяНакладнаяОбъект.Проведен;
ОтменитьТранзакцию();
Сообщить(ПриходнаяНакладнаяОбъект.Проведен); //ложь
Сообщить(Проведен);  //истина

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