在实施IEnlistmentNotification时我应该在哪里执行操作?

mat*_*i82 5 .net c# transactions transactionscope

我试图通过实现IEnlistmentNotification接口创建自定义"资源管理器" .该接口有以下方法:

  • 准备()
  • 承诺()
  • 回滚()
  • 怀疑()

虽然很清楚回滚代码应该在Rollback()方法中,但我不确定在哪种方法中应该实现执行实际操作的代码?它应该在Prepare()或Commit()中,还是在类中的一些其他自定义方法中,这些方法将从TransactionScope块内部的外部代码中调用?

Mar*_*lis 8

实际工作应该用另一种方法进行.准备和提交是为了实现两阶段提交机制.

模式如下:

using(var transaction = new TransactionScope())
{
    var rc1 = new ResourceManager();
    rc1.DoWork();
    var rc2 = new ResourceManager();
    rc2.DoWork();
    transaction.Complete();
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,DoWork应执行该操作.退出事务范围时,将调用两个资源管理器的Prepare方法.如果他们都调用了enlistment.Prepared();那么将调用两个管理器的Commit方法. 这个提交永远不会失败!

例如,在处理文件时, DoWork应重命名文件以指示您正在处理它,然后读取并处理该文件.如果任一操作失败,则应抛出异常,从而调用Rollback. 回滚应该将文件重命名为其原始名称. 准备可以重命名文件以指示它应该被删除并检查是否允许删除该文件.如果任一操作失败,则应抛出异常. 然后,Commit会实际删除该文件.这不会失败,因为我们已经检查了安全性,但即使这样做,也不应该抛出异常.

您实际上可以在Prepare方法中删除该文件并调用enlistment.Done();.这表明不再需要对Commit的调用.但问题是,在删除文件后,另一个资源管理器可能会在其Prepare中抛出异常.因为您表示您已完成,所以不会调用您的回滚方法.即使被召唤,你也无法恢复行动......

我希望这能解释一下......