Cómo detectar una transacción Abortar en un ServicedComponent?
-
08-10-2019 - |
Pregunta
Estoy intentando crear un System.EnterpriseServices.ServicedComponent con el fin de participar en una transacción distribuida. Mi principal método miradas algo como esto:
public void DoSomething()
{
try
{
// do something useful
// vote for commit
if (ContextUtil.IsInTransaction)
ContextUtil.MyTransactionVote = TransactionVote.Commit;
}
catch
{
// or shoud I use ContextUtil.SetAbort() instead?
if (ContextUtil.IsInTransaction)
ContextUtil.MyTransactionVote = TransactionVote.Abort;
throw;
}
}
Lo que estoy tratando de hacer es detectar si la transacción distribuida se ha anulado (o deshace) y luego proceder a deshacer mis cambios también. Por ejemplo, podría haber creado un archivo en el disco, o hecho algunos efectos secundarios que hay que hacer.
Me han tratado de controlar el evento SystemTransaction.TransactionCompleted o inspeccionado el estado de la SystemTransaction en el método Dispose () sin éxito.
Yo entiendo que esto es similar a una "compensación" en lugar de "transacción".
¿Lo que yo estoy tratando de hacer aún tiene sentido?
Solución 2
contestar a mi propia pregunta, esto es posible mediante la derivación de la ServicedComponent de System.Transactions.IEnlistmentNotification también.
Otros consejos
lo recomiendo a no manejar la transacción de tal manera a menos que lo necesite.
Si usted quiere que su operación para abortar voto si cualquiera de las otras operaciones que intervienen en la cadena falla, o votar por cometer si todo ha ido bien; basta con colocar un atttribute [AutoComplete]
(ver Comentarios sección en este artículo ) justo por encima de su método de declaración.
De este modo, la transacción actual se interrumpirá si acaso un aumentos de excepción y se completará en caso contrario, de forma automática.
Considere el código de abajo (esto podría ser una clase de componente revisado típico):
using System.EnterpriseServices;
// Description of this serviced component
[Description("This is dummy serviced component")]
public MyServicedComponent : ServicedComponent, IMyServiceProvider
{
[AutoComplete]
public DoSomething()
{
try {
OtherServicedComponent component = new OtherServicedComponent()
component.DoSomethingElse();
// All the other invocations involved in the current transaction
// went fine... let's servicedcomponet vote for commit automatically
// due to [AutoComplete] attribute
}
catch (Exception e)
{
// Log the failure and let the exception go
throw e;
}
}
}