【问题标题】:How to Detect a Transaction Abort in a ServicedComponent?如何检测 ServicedComponent 中的事务中止?
【发布时间】:2010-12-10 22:34:16
【问题描述】:

我正在尝试创建一个 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 事件或在 Dispose() 方法中检查 SystemTransaction 的状态,但均未成功。

我理解这类似于“补偿”而不是“交易”。

我正在尝试做的事情是否有意义?

【问题讨论】:

  • 好吧,有点回答我自己的问题,这也可以通过从 System.Transactions.IEnlistmentNotification 派生 ServicedComponent 来实现。但是我无法让它工作 - 相反,我系统地得到了一个 ObjectDisposedException。

标签: .net transactions rollback distributed-transactions servicedcomponent


【解决方案1】:

除非您需要,否则我建议不要以这种方式管理交易。

如果您希望您的操作在链中涉及的任何其他操作失败时投票中止,或者如果一切正常则投票提交;只需在方法声明的上方放置一个[AutoComplete] 属性(参见article备注部分)。

通过这种方式,当前事务将被中止,以防出现异常,否则将自动完成。

考虑下面的代码(这可能是一个典型的服务组件类):

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

【讨论】:

  • 感谢您的详细建议。
  • 不客气,Maxime,事实上我意识到这是一篇相当老的帖子为时已晚,但可能对其他人有帮助。
【解决方案2】:

回答我自己的问题,这也可以通过从 System.Transactions.IEnlistmentNotification 派生 ServicedComponent 来实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    相关资源
    最近更新 更多