Confirmar una transacción en fase única y múltipleCommitting a Transaction in Single-Phase and Multi-Phase

Un administrador de recursos (RM) administra cada recurso utilizado, cuyas acciones coordina un administrador de transacciones (TM).Each resource used in a transaction is managed by a resource manager (RM), whose actions are coordinated by a transaction manager (TM). El dar de alta recursos como participantes en una transacción tema explica cómo pueden inscribirse en una transacción de un recurso (o varios recursos).The Enlisting Resources as Participants in a Transaction topic discusses how a resource (or multiple resources) can be enlisted in a transaction. En este tema se trata cómo la confirmación de la transacción se puede coordinar entre los recursos inscritos.This topic discusses how transaction commitment can be coordinated among enlisted resources.

Al final de la transacción, la aplicación pide confirmar la transacción o revertirlaAt the end of the transaction, the application requests the transaction to be either committed or rolled back. 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.The transaction manager must eliminate risks like some resource managers voting to commit while others voting to roll back the transaction.

Si su transacción implica más de un recurso, debe realizar una confirmación en dos fases (2PC).If your transaction involves more than one resource, you must perform a two-phase commit (2PC). El protocolo de confirmación en dos fases (la fase de preparación y la de confirmación) asegura que cuando la transacción finaliza, todos los cambios a todos los recursos se confirman o se deshacen.The two-phase commit protocol (the prepare phase and the commit phase) ensures that when the transaction ends, all changes to all resources are either totally committed or fully rolled back. Todos los participantes se informan a continuación del resultado final.All the participants are then informed of the final result. Para obtener una explicació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.For a detailed discussion of the two-phase commit protocol, please consult the book "Transaction Processing : Concepts and Techniques (Morgan Kaufmann Series in Data Management Systems) ISBN:1558601902" by Jim Gray.

También puede optimizar el rendimiento de su transacción tomando parte en el protocolo de confirmación de fase única.You can also optimize your transaction's performance by taking part in the Single Phase Commit protocol. Para obtener más información, consulte optimización con la confirmación de fase única y fase única Promovible.For more information, see Optimization using Single Phase Commit and Promotable Single Phase Notification.

Si solo desea ser informado del resultado de una transacción, y no desea participar para votar, se debería registrar para el evento TransactionCompleted.If you just want to be informed of a transaction's outcome, and do not want to participate in voting, you should register for the TransactionCompleted event.

Confirmación en dos fases (2PC)Two-phase Commit (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.In the first transaction phase, the transaction manager queries each resource to determine whether a transaction should be committed or rolled back. 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.In the second transaction phase, the transaction manager notifies each resource of the outcome of its queries, allowing it to perform any necessary cleanup.

Para participar en este tipo de transacción, un administrador de recursos debe implementar la interfaz IEnlistmentNotification, que proporciona métodos que el TM llamará como notificaciones durante una 2PC.To participate in this kind of transaction, a resource manager must implement the IEnlistmentNotification interface, which provides methods that are called by the TM as notifications during a 2PC. En el siguiente ejemplo se muestra un ejemplo de dicha implementación.The following sample shows an example of such implementation.

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();
    }
}
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

Preparar la fase (fase 1)Prepare phase (Phase 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.Upon receiving a Commit request from the application, the transaction manager begins the Prepare phase of all the enlisted participants by calling the Prepare method on each enlisted resource, in order to obtain each resource's vote on the transaction.

Su administrador de recursos que implementa la interfaz IEnlistmentNotification debería implementar primero el método Prepare(PreparingEnlistment) como las presentaciones del ejemplo simples siguientes.Your resource manager that implements the IEnlistmentNotification interface should first implement the Prepare(PreparingEnlistment) method as the following simple example shows.

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.When the durable resource manager receives this call, it should log the transaction's recovery information (available by retrieving the RecoveryInformation property) and whatever information is necessary to complete the transaction on commit. Esto no necesita ser realizado dentro del método Prepare porque RM puede hacer esto en un subproceso de trabajo.This does not need to be performed within the Prepare method because the RM can do this on a worker thread.

Cuando RM ha finalizado su trabajo de preparación, debería votar para confirmar o deshacer llamando aPrepared o al método ForceRollback.When the RM has finished its prepare work, it should vote to commit or roll back by calling the Prepared or ForceRollback method. Observe que la clase PreparingEnlistment hereda un método Done de la clase Enlistment.Notice that the PreparingEnlistment class inherits a Done method from the Enlistment class. 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 solo 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.If you call this method on the PreparingEnlistment callback during the Prepare phase, it informs the TM that it is a Read-Only enlistment (that is, resource managers that can read but cannot update transaction-protected data) and the RM receives no further notifications from the transaction manager as to the outcome of the transaction in phase 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.The application is told of the successful commitment of the transaction after all the resource managers vote Prepared.

Confirmar la fase (fase 2)Commit phase (Phase 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.In the second phase of the transaction, if the transaction manager receives successful prepares from all the resource managers (all the resource managers have invoked Prepared at the end of phase 1), it invokes the Commit method for each resource manager. Los administradores de recursos pueden realizar a continuación los cambios duraderos y completar la confirmación.The resource managers can then make the changes durable and complete the commit.

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.If any resource manager reported a failure to prepare in phase 1, the transaction manager invokes the Rollback method for each resource manager and indicates the failure of the commit to the application.

Así, su administrador de recursos debería implementar los métodos siguientes.Thus, your resource manager should implement the following methods.

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.The RM should perform any work necessary to finish the transaction based on the notification type, and inform the TM that it has finished by calling Done method on the Enlistment parameter. Este trabajo se puede hacer en un subproceso de trabajo.This work can be done on a worker thread. Tenga en cuenta que las notificaciones de la fase 2 pueden suceder alineadas en el mismo subproceso que llamó al método Prepared en la fase 1.Note that the phase 2 notifications can happen inline on the same thread that called the Prepared method in phase 1. Como tal, no debería realizar ningún trabajo después de la llamada a Prepared (por ejemplo, liberando bloqueos) que debería esperar que se habrían completado antes de recibir las notificaciones de la fase 2.As such, you should not do any work after the Prepared call (for example, releasing locks) that you would expect to have completed before receiving the phase 2 notifications.

Implementar InDoubtImplementing InDoubt

Finalmente, debería implementar el método InDoubt para el administrador de recursos volátil.Finally, you should implement the InDoubt method for the volatile resource manager. 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.This method is called if the transaction manager loses contact with one or more participants, so their status is unknown. 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.If this occurs, you should log this fact so that you can investigate later whether any of the transaction participants has been left in an inconsistent state.

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

Optimización de confirmación de fase únicaSingle Phase Commit Optimization

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.The Single Phase Commit protocol is more efficient at run time because all updates are done without any explicit coordination. Para obtener más información sobre este protocolo, consulte optimización con la confirmación de fase única y fase única Promovible.For more information on this protocol, see Optimization using Single Phase Commit and Promotable Single Phase Notification.

Vea tambiénSee Also

Optimización mediante el uso de la confirmación de fase única y de la inscripción de fase única promovibleOptimization using Single Phase Commit and Promotable Single Phase Notification
Inscribir recursos como participantes en una transacciónEnlisting Resources as Participants in a Transaction