应该在哪里实施IEnlistmentNotification当我执行操作? [英] Where should I perform action when implementing IEnlistmentNotification?

查看:312
本文介绍了应该在哪里实施IEnlistmentNotification当我执行操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个自定义的资源管理器通过实施<一个href="http://msdn.microsoft.com/en-us/library/system.transactions.ienlistmentnotification%28v=vs.110%29.aspx"相对=nofollow> IEnlistmentNotification 接口。这个接口有以下方法:

I am trying to create a custom "resource manager" by implementing IEnlistmentNotification interface. This interface has following methods:

  • prepare()
  • 在提交()
  • 回滚()
  • 的不确定()

虽然很明显,回退code应该在rollback()方法,我不知道我应该实现了code执行实际操作哪种方法吗?如果他走在prepare()或提交()或者类中的其他一些自定义的方法将被来自外太空code称为从TransactionScope的块里面?

While it's clear that rollback code should go in Rollback() method I am not sure in which method should I implement the code that performs the actual operation? Should it go in Prepare() or Commit() or maybe some other custom method in the class that will be called from outer code from inside of TransactionScope block?

推荐答案

在实际工作中应以另一种方法来进行。 prepare,并承诺在那里实现两阶段提交的机制。

The actual work should be performed in another method. Prepare and Commit are there to implement a 2-phase commit mechanism.

的模式如下:

using(var transaction = new TransactionScope())
{
    var rc1 = new ResourceManager();
    rc1.DoWork();
    var rc2 = new ResourceManager();
    rc2.DoWork();
    transaction.Complete();
}

在这个例子中,DoWork的应执行的操作。 当退出的事务范围,无论是资源管理器的prepare方法将被调用。 如果他们都被称为入伍prepared(); 那么这两个经理的提交方法将被调用。 犯下应该永远不会失败!

In this example the DoWork should execute the action. When exiting the transaction scope, the Prepare method of both resource managers will be called. If they both called enlistment.Prepared(); then the Commit methods of both managers will be called. That commit should never fail!

例如,在处理文件时, 的DoWork 要重命名文件,表示要处理它,然后读取和处理文件。如果任一操作失败,它应该抛出一个异常,导致回滚被调用。 回滚要重命名文件恢复到原来的名称。 prepare 可以重命名文件,以表明它应该被删除,并检查它是否被允许删除该文件。如果任一操作失败,它应该抛出一个异常。 提交然后将实际删除文件。这不会失败,因为我们已经检查了安全性,但即使是这样,它不应该抛出异常。

For example, when working with files, DoWork should rename the file to indicate you are processing it, and then read and process the file. If either action fails, it should throw an exception causing the Rollback to be called. Rollback should rename the file back to its original name. Prepare could rename the file to indicate it should be deleted and check whether it is allowed to delete the file. If either action fails, it should throw an exception. Commit would then actually delete the file. This will not fail because we already checked the security, but even if it does, it should not throw an exception.

其实你可以删除prepare方法的文件,并调用 enlistment.Done(); 。这表明不需要调用提交了。但是与该问题是,你删除的文件后,其他的资源管理器可以扔在了prepare异常。因为你表明你做了,你回滚方法将不会被调用。并且即使是所谓的,就没有办法让你恢复你的行动......

You could actually delete the file in the Prepare method and call enlistment.Done();. This would indicate that the call to Commit is not needed anymore. But the problem with that is that after you deleted the file, the other resource manager could throw an exception in its Prepare. Because you indicated you were Done, your rollback method will not be called. And even if is was called, there would be no way for you to recover your action...

我希望这解释了事情有点...

I hope this explains things a bit...

这篇关于应该在哪里实施IEnlistmentNotification当我执行操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆