Как обнаружить прерывание транзакции в обслуживаемом компоненте? - PullRequest
1 голос
/ 11 декабря 2010

Я пытаюсь создать System.EnterpriseServices.ServicedComponent для участия в распределенной транзакции. Мой основной метод выглядит примерно так:

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

Я пытаюсь определить, была ли распределенная транзакция прервана (или откатана), а затем приступить к откату моих изменений. Например, я мог создать файл на диске или сделать некоторые побочные эффекты, которые нужно отменить.

Я пытался обработать событие SystemTransaction.TransactionCompleted или проверил состояние SystemTransaction в методе Dispose (), но безуспешно.

Я понимаю, что это похоже на "компенсацию", а не на "транзакцию".

Имеет ли смысл то, что я пытаюсь сделать?

Ответы [ 2 ]

1 голос
/ 11 февраля 2012

Я бы порекомендовал не управлять транзакцией таким образом, если вам это не нужно.

Если вы хотите, чтобы ваша операция провалила голосование в случае сбоя любой из других операций, участвующих в цепочке, или проголосовала за принятие, есливсе прошло хорошо;просто поместите атрибут [AutoComplete] (см. раздел Замечания в этой статье ) чуть выше объявления вашего метода.

Таким образом, текущая транзакция будет прервана только весли исключение возникает и будет выполнено в противном случае, автоматически.

Рассмотрим приведенный ниже код (это может быть типичный класс обслуживаемых компонентов):

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;
        }
    }
}
0 голосов
/ 28 февраля 2011

Отвечая на мой собственный вопрос, это возможно, если получить ServicedComponent из System.Transactions.IEnlistmentNotification .

...