这样的代码是不会提升为DTC管理的,我们加一行代码:
public static void StartCopy() { using (TransactionScope transcope = new TransactionScope()) { IDtcTransaction idtc = TransactionInterop.GetDtcTransaction(Transaction.Current); transcope.Complete(); } } |
先解释一下TransactionInterop类的作用,来自MSDN的说明:
“促进System.Transactions 和以前编写的用于与 MSDTC、COM+ 或 System.EnterpriseServices 进行交互的组件之间的交互。无法继承此类。”
其实该类主要用来对早期的分布式事务技术进行互操作,比如用来获取DTC相关的COM对象或者用来进行自定义的事务传播,对于复杂的Oletx(Windows平台的二进制通讯协议)协议,我们不需要关心太多核心的东西就能进行分布式事务的传递,这里可能Remoting有这个需求了。[王清培版权所有,转载请给出署名]
利用TransactionInterop.GetDtcTransaction方法确实能获取到DTC事务接口。
图1:
有了TransactionInterop类,我们后面的扩展就方便多了。
由于KTM是属于非托管实现,操作系统提供了文件操作的事务性API方法:
非事务处理 API |
事务处理 API |
CreateFile |
CreateFileTransacted |
CopyFileEx |
CopyFileTransacted |
MoveFileWithProgress |
MoveFileTransacted |
DeleteFile |
DeleteFileTransacted |
CreateHardLink |
CreateHardLinkTransacted |
CreateSymbolicLink |
CreateSymbolicLinkTransacted |
CreateDirectoryEx |
CreateDirectoryTransacted |
RemoveDirectory |
RemoveDirectoryTransacted |
通过封装这些方法就能够实现事务性的文件操作,目前.NET没有封装成熟的类库给我们使用,估计在后期的新版本类库中可能会提供。
那么我们如何使用KTM事务处理呢,很幸运的是通过MSND的连接我们能够获取到微软的事务开发人员编写的源码,下载地址为:
http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TxF2007_07.exe
源码都是通过对上面的API进行封装的,里面涉及到了很多关于内部API和COM之间的通讯细节,我们可以看看老外写的代码是复杂,也是我们学习的榜样。
上面我们说过只要夸当前应用程序域的事务处理就会自动提升为DTC事务,对于API的调用已经是出于互操作类型的,当前已经出于远程调用,DTC已经具有与托管域的交互实现,所以我们只有通过DTC进入KTM进行操作。这也是MSDN官方的解释。
图2:
我们来看一个简单的例子,该例子实现对文件的事务性删除操作。
例子1:
public static void StartDelete() { try { using (TransactionScope transcope = new TransactionScope()) { Console.WriteLine( "输入要删除的文件" ); string path = Console.ReadLine(); Microsoft.KtmIntegration.TransactedFile.Delete(path); Console.WriteLine( "是否提交事务处理?" ); if (Console.ReadLine() == "y" ) transcope.Complete(); else Transaction.Current.Rollback(); } } catch (Exception err) { Console.WriteLine(err); } |
我简单的写了一段测试代码,经过测试是OK的。KTM能很好的结合DTC、LTM进行混合的事务处理,对于我们上面引入的疑问现在能完美的解决了。
参考文章:http://msdn.microsoft.com/zh-cn/magazine/cc163388.aspx