如何检测 ServicedComponent 中的事务中止?

发布于 2024-10-07 06:05:41 字数 744 浏览 0 评论 0 原文

我正在尝试创建一个 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 的状态,但没有成功。

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

我想做的事情有意义吗?

I'm trying to create a System.EnterpriseServices.ServicedComponent in order to participate in a distributed transaction. My main method looks something like this:

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

What I'm trying to do is detecting whether the distributed transaction has been aborted (or rolled back) and then proceed to rollback my changes as well. For instance, I might have created a file on disk, or done some side effects that need to be undone.

I have tried to handle the SystemTransaction.TransactionCompleted event or inspected the state of the SystemTransaction in the Dispose() method without success.

I understand that this is similar to "compensation" rather than "transaction".

Does what I'm trying to do even make sense ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

2024-10-14 06:05:41

我建议不要以这种方式管理交易,除非你需要它。

如果您希望您的操作在链中涉及的任何其他操作失败时投票中止,或者在一切顺利时投票赞成提交;只需放置一个 [AutoComplete] 属性(请参阅此 备注部分)。 enterpriseservices.autocompleteattribute%28v=vs.71%29.aspx" rel="nofollow">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;
        }
    }
}

I would recommend to not manage the transaction in such way unless you need it.

If you want your operation to vote abort if any of the other operations involved in the chain fail, or vote for commit if everything went fine; just place an [AutoComplete] atttribute (see Remarks section at this article) just above your method's declaration.

In this way the current transaction will be aborted just in case an exception raises and will be completed otherwise, automatically.

Consider the code below (this could be a typical serviced component class):

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;
        }
    }
}
箜明 2024-10-14 06:05:41

Answering my own question, this is possible by deriving the ServicedComponent from System.Transactions.IEnlistmentNotification as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文