Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Cada recurso usado em uma transação é gerenciado por um RM (gerenciador de recursos), cujas ações são coordenadas por um TM (gerenciador de transações). O tópico Inscrever Recursos como Participantes em uma Transação discute como um recurso (ou vários recursos) pode ser inscrito em uma transação. Este tópico discute como confirmação de transação pode ser coordenada entre recursos.
No final da transação, o aplicativo solicita que a transação seja confirmada ou revertida. O Gerenciador de transações deve eliminar riscos, como alguns gerenciadores de recursos de votação para confirmar quando outro votação para reverter a transação.
Se a transação envolver mais de um recurso, você deverá realizar uma confirmação em duas fases (2PC). O protocolo de confirmação de duas fases (a fase de preparação e a fase de confirmação) garante que, quando a transação terminar, todas as alterações em todos os recursos sejam totalmente confirmadas ou totalmente revertidas. Todos os participantes são informados do resultado final. Para obter uma discussão detalhada sobre o protocolo de confirmação em duas fases, consulte o livro "Processamento de transações : conceitos e técnicas (Morgan Kaufmann Series in Data Management Systems) ISBN:1558601902" de Jim Gray.
Você também pode otimizar o desempenho da transação participando do protocolo de Confirmação de Fase Única. Para obter mais informações, confira Otimização usando a confirmação de fase única e a notificação de fase única passível de promoção.
Se você quiser apenas ser informado do resultado de uma transação e não quiser participar da votação, registre-se para o TransactionCompleted evento.
Confirmação de duas fases (2PC)
Na primeira fase da transação, o gerenciador de transações consulta cada recurso para determinar se uma transação deve ser confirmada ou revertida. Na segunda fase da transação, o gerenciador de transações notifica cada recurso do resultado de suas consultas, permitindo que ele execute qualquer limpeza necessária.
Para participar desse tipo de transação, um Gerenciador de recursos deve implementar o IEnlistmentNotification interface, que fornece métodos que são chamados pelo TM como notificações durante um 2PC. O exemplo a seguir mostra um exemplo dessa implementação.
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 in doubt 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 in doubt notification is received
'Declare done on the enlistment
myEnlistment.Done()
End Sub
End Class
Fase de preparação (Fase 1)
Ao receber um Commit solicitação do aplicativo, o Gerenciador de transações começa a fase de preparação de todos os participantes inscrita chamando o Prepare método em cada inscrito recurso, para obter um voto de cada recurso na transação.
O gerenciador de recursos que implementa a IEnlistmentNotification interface deve primeiro implementar o Prepare(PreparingEnlistment) método, como mostra o exemplo simples a seguir.
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;
}
}
Quando o Gerenciador de recursos duráveis recebe essa chamada, ele deverá registrar informações de recuperação da transação (disponível ao recuperar o RecoveryInformation propriedade) e qualquer informação é necessária para concluir a transação de confirmação. Isso não precisa ser executado dentro do Prepare método porque o RM pode fazer isso em um thread de trabalho.
Quando o RM terminou seu trabalho de preparação, devem votar para confirmar ou reverter chamando o Prepared ou ForceRollback método. Observe que a PreparingEnlistment classe herda um Done método da Enlistment classe. Se você chamar esse método no PreparingEnlistment o retorno de chamada durante a fase de preparação, ele informa o TM que é uma inscrição de somente leitura (ou seja, gerenciadores de recursos que pode ler, mas não é possível atualizar dados protegidos por transação) e o RM não recebe nenhuma notificação adicional do Gerenciador de transações sobre o resultado da transação na fase 2.
O aplicativo é informado do compromisso bem-sucedida da transação depois que todos os gerenciadores de recursos votam Prepared.
Fase de confirmação (Fase 2)
Na segunda fase da transação, se o gerenciador de transações receber confirmações bem-sucedidas de todos os gerenciadores de recursos (todos os gerenciadores de recursos tiverem invocado Prepared ao final da fase 1), ele invocará o método Commit para cada gerenciador de recursos. Os gerenciadores de recursos, faça as alterações durável e concluir a confirmação.
Se o Gerenciador de recursos relatou uma falha ao preparar na fase 1, o Gerenciador de transações invoca o Rollback método para cada Gerenciador de recursos e indica a falha da confirmação ao aplicativo.
Portanto, o gerenciador de recursos deve implementar os métodos a seguir.
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();
}
O RM deve executar qualquer trabalho necessário para concluir a transação com base no tipo de notificação e informar ao TM que ele terminou chamando o método Done no parâmetro Enlistment. Esse trabalho pode ser feito em um thread de trabalho. Observe que as notificações de fase 2 podem acontecer embutido no mesmo thread que chamou o Prepared método na fase 1. Dessa forma, você não deve fazer nenhum trabalho após a Prepared chamada (por exemplo, liberando bloqueios) que você esperaria ter concluído antes de receber as notificações da fase 2.
Implementando incertas
Por fim, você deve implementar o InDoubt método para o gerenciador de recursos volátil. Esse método é chamado se o gerenciador de transações perde contato com um ou mais participantes, portanto, seu status é desconhecido. Se isso ocorrer, você deverá registrar esse fato para que possa investigar posteriormente se algum dos participantes da transação foi deixado em um estado inconsistente.
public void InDoubt (Enlistment enlistment)
{
// log this
enlistment.Done();
}
Otimização de confirmação de fase única
O protocolo de Confirmação de Fase Única é mais eficiente em runtime porque todas as atualizações são feitas sem nenhuma coordenação explícita. Para obter mais informações sobre esse protocolo, confira Otimização usando a confirmação de fase única e a notificação de fase única passível de promoção.