Режим отложенных изменений

Отложенные изменения в базовом 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, в объектной модели данный режим действует сразу для всех объектов, с которыми выполняются изменения.

Для работы с отложенными изменения на данном уровне 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.