我正在尝试通过实现来创建自定义“资源管理器”I入伍通知 http://msdn.microsoft.com/en-us/library/system.transactions.ienlistmentnotification%28v=vs.110%29.aspx界面。该接口有以下方法:
虽然很明显回滚代码应该放在 Rollback() 方法中,但我不确定应该在哪个方法中实现执行实际操作的代码?它应该放在Prepare() 或Commit() 中,或者可能是类中的其他自定义方法,这些方法将从TransactionScope 块内部的外部代码调用?
实际工作应该用另一种方法来执行。准备和提交用于实现两阶段提交机制。
模式如下:
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。但问题是,删除文件后,另一个资源管理器可能会在其准备中抛出异常。因为您表明已完成,所以不会调用您的回滚方法。而且即使被调用,你也没有办法恢复你的动作......
我希望这能解释一些事情......
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)