Режим отложенных изменений
Отложенные изменения в базовом API
При изменении данных в обычном режиме работы автоматически вызывается серверный метод, отвечающий за запись изменений в базу данных. Такой вызов будет выполнен при каждом изменении значения поля карточки, что может привести к значительным накладным расходам при большом количестве изменений.
Для оптимизации подобных сценариев, связанных с изменением большого количества значений, предусмотрен т.н. режим отложенных изменений, при котором все изменения накапливаются на клиентской стороне и передаются на сервер одним вызовом.
Режим отложенных изменений устанавливается вызовом у объекта, реализующего интерфейс IUpdatable
, метода BeginUpdate
:
CardData card = userSession.CardManager.GetCardData(new Guid("00000000-0000-0000-0000-000000000000")); (1)
card.BeginUpdate(); (2)
1 | Получение данных карточки. |
2 | Включение режима отложенных изменений для полученной карточки. |
Когда в карточку были внесены изменения, их нужно зафиксировать в базе данных, вызвав метод EndUpdate
:
card.EndUpdate();
Также существует возможность отменить несохранённые изменения, вызвав метод CancelUpdate
:
card.CancelUpdate();
Режим отложенных изменений поддерживает не только карточка, но и другие объекты, реализующие интерфейс IUpdatable
.
-
Права доступа и ограничения для изменяемых объектов проверяются не сразу, а в момент обработки пакета изменений на сервере.
-
Множество изменений одних данных не объединяются (не заменяют друг друга), а накапливаются. Например, если значение одного поля было изменено 10 раз, то в итоговой пакет будет записано 10 транзакций, а после получения пакета сервером будут выполнены все 10 операций.
Также следует помнить, что в пределах секции режим отложенных изменений устанавливается в т.ч. и на все подчиненные объекты — подсекции, строки и поля. Если строки находятся в режиме отложенных изменений, то после перевода в этот режим родительской секции их изменения будут учитываться в контексте родительского объекта. В обратную сторону наследование не распространяется.
Если режим отложенных изменений включён для родительского объекта, то управление режимом из подчиненного объекта не допускается, т.е. нельзя, к примеру, отменить режим для секции, если он установлен в карточке.
Как правило, режим отложенных изменений устанавливается на всю карточку, так как по умолчанию вся карточка блокируется пользователем для изменения. Но возможны случаи, когда это не так, например в случае работы со справочниками.
Практический пример доступен по ссылке Пример использования режима отложенных изменений
Отложенные изменения в объектной модели
API уровня бизнес-логики по умолчанию работает в режиме, эквивалентном режиму отложенных изменений, т.е. фактически изменения накапливаются на клиентской стороне и отправляются на сервер одним вызовом. Причем в отличие от режима отложенных изменений базового API, в объектной модели данный режим действует сразу для всех объектов, с которыми выполняются изменения.
-
ObjectContext.AcceptChanges
— сохраняет все изменения в контексте объектов:BaseCard card = objectContext.GetObject<BaseCard>(new Guid("00000000-0000-0000-0000-000000000000")); (1) card.Description = "Новое описание"; (2) BaseCard otherCard = objectContext.GetObject<BaseCard>(new Guid("00000000-0000-0000-0000-000000000001")); (3) otherCard.Description = "Новое описание для другой карточки"; (4) objectContext.AcceptChanges(); (5)
1 Получение карточки. 2 Изменение данных. 3 Получение другой карточки. 4 Изменение данных другой карточки. 5 Сохранение всех изменений контекста объектов. -
ObjectContext.SaveObject
— сохраняет изменения одного конкретного объекта:objectContext.SaveObject(card); (1)
1 Сохранение изменений в изменённом объекте card
. -
ObjectContext.RollbackChanges
— отменяет все несохранённые изменения контекста объектов:objectContext.RollbackChanges();
-
ObjectContext.RollBackObject
— отменяет несохранённые изменения одного объекта:objectContext.RollBackObject(card);
Контекст объектов также предоставляет методы для сохранения и отмены изменения нескольких карточек. Полный список доступных методов см. в описании типа ObjectContext
.