我正在尝试通过实现 IEnlistmentNotification 来创建自定义“资源管理器”界面。该接口(interface)有以下方法:
- 准备()
- 提交()
- 回滚()
- 怀疑()
虽然很明显回滚代码应该放在 Rollback() 方法中,但我不确定我应该在哪个方法中实现执行实际操作的代码?它应该放在 Prepare() 或 Commit() 中,还是应该从 TransactionScope block 内部的外部代码调用的类中的其他自定义方法?
最佳答案
实际工作应该以另一种方法进行。 Prepare 和 Commit 用于实现两阶段提交机制。
模式如下:
using(var transaction = new TransactionScope())
{
var rc1 = new ResourceManager();
rc1.DoWork();
var rc2 = new ResourceManager();
rc2.DoWork();
transaction.Complete();
}
在此示例中,DoWork 应执行操作。
当退出事务范围时,将调用两个资源管理器的 Prepare 方法。
如果他们都调用了 enlistment.Prepared();
,那么将调用两个管理器的 Commit 方法。 该提交永远不会失败!
例如,在处理文件时, DoWork 应该重命名该文件以表明您正在处理它,然后读取并处理该文件。如果任何一个操作失败,它应该抛出异常导致调用回滚。 Rollback 应该将文件重命名回其原始名称。 Prepare 可以重命名文件以指示应该删除它并检查是否允许删除该文件。如果任一操作失败,它应该抛出异常。 Commit 然后会实际删除该文件。这不会失败,因为我们已经检查了安全性,但即使它失败了,也不应该抛出异常。
您实际上可以在 Prepare 方法中删除文件并调用 enlistment.Done();
。这将表明不再需要对 Commit 的调用。但这样做的问题是,在您删除文件后,其他资源管理器可能会在其 Prepare 中抛出异常。因为您表示您已完成,所以不会调用您的回滚方法。即使调用了,您也无法恢复操作...
我希望这能解释一些事情......
关于c# - 实现 IEnlistmentNotification 时我应该在哪里执行操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21094406/