Partilhar via


Usar transações para atualizar o modelo

As transações garantem que as alterações feitas na loja sejam tratadas como um grupo. As alterações agrupadas podem ser confirmadas ou revertidas como uma única unidade.

Sempre que o seu código de programa modificar, adicionar ou excluir qualquer elemento no Armazém do SDK de Visualização e Modelagem do Visual Studio, deverá fazê-lo dentro de uma transação. Deve haver uma instância ativa de Transaction associada à Loja quando ocorrer a alteração. Isso se aplica a todos os elementos do modelo, relações, formas, diagramas e suas propriedades.

O mecanismo de transação ajuda a evitar estados inconsistentes. Se ocorrer um erro durante uma transação, todas as alterações serão revertidas. Se o usuário executar um comando Desfazer, cada transação recente será tratada como uma única etapa. O usuário não pode desfazer partes de uma alteração recente, a menos que você as coloque explicitamente em transações separadas.

Abrir uma transação

O método mais conveniente de gerenciar uma transação é com uma using declaração anexada em uma try...catch declaração:

Store store; ...
try
{
  using (Transaction transaction =
    store.TransactionManager.BeginTransaction("update model"))
    // Outermost transaction must always have a name.
  {
    // Make several changes in Store:
    Person p = new Person(store);
    p.FamilyTreeModel = familyTree;
    p.Name = "Edward VI";
    // end of changes to Store

    transaction.Commit(); // Don't forget this!
  } // transaction disposed here
}
catch (Exception ex)
{
  // If an exception occurs, the Store will be
  // rolled back to its previous state.
}

Se ocorrer uma exceção que impeça o final Commit() durante as alterações, a Loja será redefinida para o estado anterior. Isso ajuda a garantir que os erros não deixem o modelo em um estado inconsistente.

Você pode fazer qualquer número de alterações dentro de uma transação. Você pode abrir novas transações dentro de uma transação ativa. As transações aninhadas devem ser confirmadas ou revertidas antes que a transação que contém termine. Para obter mais informações, consulte o exemplo da TransactionDepth propriedade.

Para tornar suas alterações permanentes, você deve Commit fazer a transação antes de ser descartada. Se ocorrer uma exceção que não seja detetada dentro da transação, a Loja será redefinida para seu estado antes das alterações.

Reverter uma transação

Para garantir que a Loja permaneça ou volte ao seu estado anterior à transação, você pode usar uma destas táticas:

  1. Levante uma exceção que não seja capturada dentro do escopo da transação.

  2. Reverter explicitamente a transação:

    this.Store.TransactionManager.CurrentTransaction.Rollback();
    

As transações não afetam objetos que não são de armazenamento

As transações controlam apenas o estado da Loja. Eles não podem desfazer alterações parciais que foram feitas em itens externos, como arquivos, bancos de dados ou objetos que você declarou com tipos comuns fora da definição DSL.

Se uma exceção puder deixar essa alteração inconsistente com a Loja, você deverá lidar com essa possibilidade no manipulador de exceções. Uma maneira de garantir que os recursos externos permaneçam sincronizados com os objetos Store é associar cada objeto externo a um elemento no repositório usando manipuladores de eventos. Para obter mais informações, consulte Manipuladores de eventos propagam alterações fora do modelo.

As regras são executadas no final de uma transação

No final de uma transação, antes que a transação seja descartada, as regras anexadas aos elementos na loja são acionadas. Cada regra é um método que é aplicado a um elemento de modelo que foi alterado. Por exemplo, existem regras de "correção" que atualizam o estado de uma Forma quando o seu elemento de modelo é alterado e que criam uma Forma quando um elemento de modelo é criado. Não há uma ordem de disparo especificada. Uma alteração feita por uma regra pode acionar outra regra.

Pode definir as suas próprias regras. Para obter mais informações sobre regras, consulte Respondendo e propagando alterações.

As regras não são acionadas após um comando de desfazer, refazer ou reversão.

Contexto da transação

Cada transação tem um dicionário no qual você pode armazenar qualquer informação que desejar:

store.TransactionManager

.CurrentTransaction.TopLevelTransaction

.Context.Add(aKey, aValue);

Isso é especialmente útil para transferir informações entre regras.

Estado da transação

Em alguns casos, você precisa evitar propagar uma alteração se a alteração for causada por desfazer ou refazer uma transação. Isso pode acontecer, por exemplo, se você escrever um manipulador de valor de propriedade que possa atualizar outro valor na Store. Como a operação de anular redefine todos os valores no armazenamento para os seus estados anteriores, não é necessário calcular valores atualizados. Use este código:

if (!this.Store.InUndoRedoOrRollback) {...}

As regras podem ser acionadas quando o armazenamento está sendo carregado inicialmente de um arquivo. Para evitar responder a essas alterações, use:

if (!this.Store.InSerializationTransaction) {...}