Как обнаружить прерывание транзакции в обслуживаемом компоненте?
Я пытаюсь создать 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 ответа
Отвечая на мой собственный вопрос, это возможно, если получить ServicedComponent из System.Transactions.IEnlistmentNotification.
Я бы порекомендовал не управлять транзакцией таким образом, если вам это не нужно.
Если вы хотите, чтобы ваша операция проголосовала за прерывание, если любая из других операций, участвующих в цепочке, потерпела неудачу, или проголосуйте за коммит, если все прошло нормально; просто поместите [AutoComplete]
atttribute (см. раздел " Примечания " в этой статье) чуть выше объявления вашего метода.
Таким образом, текущая транзакция будет прервана на случай, если возникнет исключение, и будет выполнена автоматически в противном случае.
Рассмотрим код ниже (это может быть типичный класс обслуживаемых компонентов):
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;
}
}
}