Compartir vía


Usar transacciones para actualizar el modelo

Las transacciones garantizan que los cambios realizados en el almacén se manejen como un grupo. Los cambios agrupados se pueden confirmar o revertir como una sola unidad.

Cada vez que el código del programa modifica, agrega o elimina cualquier elemento del Store en el SDK de visualización y modelado de Visual Studio, debe hacerlo dentro de una transacción. Debe haber una instancia activa de Transaction asociada a la Tienda cuando se produzca el cambio. Esto se aplica a todos los elementos del modelo, relaciones, formas, diagramas y sus propiedades.

El mecanismo de transacción le ayuda a evitar estados incoherentes. Si se produce un error durante una transacción, se revierten todos los cambios. Si el usuario realiza un comando Deshacer, cada transacción reciente se trata como un solo paso. El usuario no puede deshacer partes de un cambio reciente, a menos que los coloque explícitamente en transacciones independientes.

Apertura de una transacción

El método más conveniente para gestionar una transacción es con una using sentencia incluida en una try...catch sentencia:

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.
}

Si se produce una excepción que impide que se produzca el final Commit() durante los cambios, la Tienda se restablecerá a su estado anterior. Esto le ayuda a asegurarse de que los errores no dejan el modelo en un estado incoherente.

Puede realizar cualquier número de cambios dentro de una transacción. Puede abrir nuevas transacciones dentro de una transacción activa. Las transacciones anidadas deben confirmarse o revertirse antes de que finalice la transacción contenedora. Para obtener más información, vea el ejemplo de la TransactionDepth propiedad .

Para realizar los cambios permanentes, debe Commit realizar la transacción antes de eliminarla. Si se produce una excepción que no se detecta dentro de la transacción, la Tienda se restablecerá a su estado antes de los cambios.

Revertir una transacción

Para asegurarse de que la Tienda permanece en su estado o revierte a su estado antes de la transacción, puede usar cualquiera de estas tácticas:

  1. Genere una excepción que no se detecte dentro del ámbito de la transacción.

  2. Revierte explícitamente la transacción:

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

Las transacciones no afectan a objetos que no son de almacén

Las transacciones solo rigen el estado de la Tienda. No pueden deshacer cambios parciales realizados en elementos externos como archivos, bases de datos u objetos declarados con tipos normales fuera de la definición de DSL.

Si una excepción podría dejar este cambio incoherente con la Tienda, debe tratar con esa posibilidad en el controlador de excepciones. Una manera de asegurarse de que los recursos externos permanecen sincronizados con los objetos Store es acoplar cada objeto externo a un elemento en el almacén mediante controladores de eventos. Para obtener más información, vea Controladores de eventos propagan cambios fuera del modelo.

Las reglas se activan al final de una transacción

Al final de una transacción, antes de ser cerrada la transacción, se activan las reglas asociadas a elementos en el almacén. Cada regla es un método que se aplica a un elemento de modelo que ha cambiado. Por ejemplo, hay reglas de "corrección" que actualizan el estado de una forma cuando su elemento de modelo ha cambiado y que crean una forma cuando se crea un elemento de modelo. No hay ningún orden de activación especificado. Un cambio realizado por una regla puede desencadenar otra regla.

Puede definir sus propias reglas. Para obtener más información sobre las reglas, vea Responder a los cambios y propagarlos.

Las reglas no se activan después de deshacer, rehacer o un comando de reversión.

Contexto de transacción

Cada transacción tiene un diccionario en el que puede almacenar cualquier información que desee:

store.TransactionManager

.CurrentTransaction.TopLevelTransaction

.Context.Add(aKey, aValue);

Esto es especialmente útil para transferir información entre reglas.

Estado de transacción

A veces, debe evitar propagar un cambio si el cambio es causado por deshacer o rehacer una transacción. Esto puede ocurrir, por ejemplo, si usted escribe un manejador de valores de propiedad que puede actualizar otro valor en el Store. Dado que la operación de deshacer restablece todos los valores del almacén a sus estados anteriores, no es necesario calcular los valores actualizados. Use este código:

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

Las reglas se pueden activar cuando la tienda se carga inicialmente desde un archivo. Para evitar responder a estos cambios, use:

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