Share via


Confirmar una transacción en fase única y múltiple

Un administrador de recursos (RM) administra cada recurso utilizado, cuyas acciones coordina un administrador de transacciones (TM). En este tema Dar de alta los recursos como participantes en una transacción se trata cómo un recurso (o múltiples recursos) pueden inscribirse en una transacción. En este tema se trata cómo la confirmación de la transacción se puede coordinar entre los recursos inscritos.

Al final de la transacción, la aplicación pide confirmar la transacción o revertirla El administrador de transacciones debe eliminar los riesgos como algunos administradores de recursos que votan para confirmar mientras que otros votan para deshacer la transacción.

Si su transacción implica más de un recurso, deberá realizar una confirmación en dos fases (2PC). El protocolo de confirmación en dos fases (la fase de preparación y la fase de la confirmación) asegura que cuando la transacción finaliza, todos los cambios a todos los recursos son o totalmente confirmados o totalmente deshechos. Todos los participantes se informan a continuación del resultado final. Para obtener una discusión detallada del protocolo de confirmación en dos fases, consulte el libro "Procesamiento de transacciones: Conceptos y Técnicas (Serie de Morgan Kaufmann en Sistemas de administración de datos) ISBN:1558601902" por Jim Gray.

También puede optimizar el rendimiento de su transacción tomando parte en el protocolo de confirmación de fase única. Para obtener más información, consulte Optimización con la confirmación de fase única y la confirmación de fase única promocionable.

Si sólo desea ser informado del resultado de una transacción, y no desea participar para votar, se debería registrar para el evento TransactionCompleted.

Confirmación en dos fases (2PC)

En la primera fase de la transacción, el administrador de transacciones consulta cada recurso para determinar si una transacción se debería confirmar o deshacer. En la segunda fase de la transacción, el administrador de transacciones notifica a cada recurso el resultado de sus consultas, permitiéndole realizar cualquier limpieza necesaria.

Para participar en este tipo de transacción, un administrador de recursos debe implementar la interfaz IEnlistmentNotification, que proporciona métodos a los que son llamados por la TM como notificaciones durante un 2PC. Lo siguiente muestra un ejemplo de dicha implementación.

Public Class EnlistmentClass
    Implements IEnlistmentNotification

    Public Sub Prepare(ByVal myPreparingEnlistment As PreparingEnlistment) Implements System.Transactions.IEnlistmentNotification.Prepare
        Console.WriteLine("Prepare notification received")

        'Perform transactional work

        'If work finished correctly, reply with prepared
        myPreparingEnlistment.Prepared()
    End Sub

    Public Sub Commit(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.Commit
        Console.WriteLine("Commit notification received")

        'Do any work necessary when commit notification is received

        'Declare done on the enlistment
        myEnlistment.Done()
    End Sub

    Public Sub Rollback(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.Rollback
        Console.WriteLine("Rollback notification received")

        'Do any work necessary when rollback notification is received

        'Declare done on the enlistment
        myEnlistment.Done()
    End Sub

    Public Sub InDoubt(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.InDoubt
        Console.WriteLine("In doubt notification received")

        'Do any work necessary when indout notification is received

        'Declare done on the enlistment
        myEnlistment.Done()
    End Sub
End Class
class myEnlistmentClass : IEnlistmentNotification
{
    public void Prepare(PreparingEnlistment preparingEnlistment)
    {
        Console.WriteLine("Prepare notification received");

        //Perform transactional work

        //If work finished correctly, reply prepared
        preparingEnlistment.Prepared();

        // otherwise, do a ForceRollback
        preparingEnlistment.ForceRollback();
    }

    public void Commit(Enlistment enlistment)
    {
        Console.WriteLine("Commit notification received");

        //Do any work necessary when commit notification is received

        //Declare done on the enlistment
        enlistment.Done();
    }

    public void Rollback(Enlistment enlistment)
    {
        Console.WriteLine("Rollback notification received");

        //Do any work necessary when rollback notification is received

        //Declare done on the enlistment
        enlistment.Done();
    }

    public void InDoubt(Enlistment enlistment)
    {
        Console.WriteLine("In doubt notification received");

        //Do any work necessary when indout notification is received
        
        //Declare done on the enlistment
        enlistment.Done();
    }
}

Preparar la fase (fase 1)

Al recibir una solicitud Commit de la aplicación, el administrador de transacciones comienza la fase de preparación de todos los participantes alistados llamando al método Prepare en cada recurso alistado para obtener el voto de cada recurso en la transacción.

Su administrador de recursos que implementa la interfaz IEnlistmentNotification debería implementar primero el método Prepare como las presentaciones del ejemplo simples siguientes.

public void Prepare(PreparingEnlistment preparingEnlistment)
{
     Console.WriteLine("Prepare notification received");
     //Perform work

     Console.Write("reply with prepared? [Y|N] ");
     c = Console.ReadKey();
     Console.WriteLine();
 
     //If work finished correctly, reply with prepared
     if ((c.KeyChar == 'Y') || (c.KeyChar == 'y'))
     {
          preparingEnlistment.Prepared();
          break;
     }

     // otherwise, do a ForceRollback
     else if ((c.KeyChar == 'N') || (c.KeyChar == 'n'))
     {
          preparingEnlistment.ForceRollback();
          break;
     }
}

Cuando el administrador de recursos duradero recibe esta llamada, debería registrar la información de la recuperación (disponible recuperando la propiedad RecoveryInformation ) de la transacción y cualquier información es necesaria para completar la transacción de confirmación. Esto no necesita ser realizado dentro del método Prepare porque RM puede hacer esto en un subproceso de trabajo.

Cuando RM ha finalizado su trabajo de preparación, debería votar para confirmar o deshacer llamando aPrepared o al método ForceRollback. Observe que la clase PreparingEnlistment hereda un método Done de la clase Enlistment. Si llama a este método en la devolución de llamada PreparingEnlistment durante la fase de preparación, éste informa al TM de que es una inscripción de sólo lectura (es decir, administradores de recursos que pueden leer pero no pueden actualizar los datos protegidos por transacción) y el RM no recibe ninguna notificación más extensa del administrador de transacciones acerca del resultado de la transacción en fase 2.

Se cuenta en la aplicación la exitosa confirmación de la transacción después de que todos los administradores de recursos voten Prepared.

Confirmar la fase (fase 2)

En la segunda fase de la transacción, si el administrador de transacciones recibe correcta preparación de todos los administradores de recursos (todos los administradores de recursos han invocado Prepared al final de fase 1), invoca el método Commit para cada administrador de recursos. Los administradores de recursos pueden realizar a continuación los cambios duraderos y completar la confirmación.

Si cualquier administrador de recursos informa de un error para preparar en fase 1, el administrador de transacciones invoca el método Rollback para cada administrador de recursos e indica el error de la confirmación a la aplicación.

Así, su administrador de recursos debería implementar los métodos siguientes.

public void Commit (Enlistment enlistment)
{
     // Do any work necessary when commit notification is received

     // Declare done on the enlistment
     enlistment.Done();
}

public void Rollback (Enlistment enlistment)
{
     // Do any work necessary when rollback notification is received

     // Declare done on the enlistment  
     enlistment.Done();  
}

El administrador de recursos realizará las operaciones necesarias para finalizar la transacción basada en el tipo de notificación y después informará al administrador de transacciones de que ha finalizado llamando al método Done en el parámetro Enlistment. Este trabajo se puede hacer en un subproceso de trabajo. Observe que las notificaciones de la fase 2 pueden tener lugar en línea en el mismo subproceso que llamó al método Prepared en la fase 1. Como tal, no tendrá que realizar ningún trabajo después de la llamada a Prepared (por ejemplo, liberar bloqueos) que se debe haber llevado a cabo antes de recibir las notificaciones de la fase 2.

Implementar InDoubt

Finalmente, debería implementar el método InDoubt para el administrador de recursos volátil. Se llama a este método si el administrador de transacciones pierde el contacto con uno o más participantes, por lo que su estado es desconocido. Si esto se produce, debería registrar este hecho para que se pueda investigar después si cualquiera de los participantes de la transacción ha quedado en un estado incoherente.

public void InDoubt (Enlistment enlistment)
{
     // log this
     enlistment.Done();
}

Optimización de confirmación de fase única

La fase única el protocolo de confirmación es más eficaz en el tiempo de ejecución porque todas las actualizaciones se hacen sin ninguna coordinación explícita. Para obtener más información sobre este protocolo vea Optimización con la confirmación de fase única y la confirmación de fase única promocionable.

Consulte también

Conceptos

Optimización con la confirmación de fase única y la confirmación de fase única promocionable
Dar de alta los recursos como participantes en una transacción

Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.