使用KTM(内核事务管理器)进行文件事务处理

在本人最近的几篇关于事务处理的文章中,从事务处理的整体概念到具体的C#代码的实践操作基本上都已经能满足日常的开发需求。文章中大部分的事务范围类的操作都是局限于数据库,在本人的“.NET简谈自定义事务资源管理器 ”一文中我虽然实现了一个简单的自定义资源管理器,其实也能满足基本的项目需求,核心功能也实现了,但是对于文件事务操作我们是力不从心的。[王清培版权所有,转载请给出署名]

从数据库到自定义资源管理器都能参与到事务处理中来,在必要的时候保证数据的完整性,那么我们缺一个类型的资源操作,当然您也许早就想问了,关于文件系统的事务操作怎么办?那么关于文件的事务操作是否有成熟的解决方案了,这点在前几年还真没办法,但是最近微软已经发布了关于事务性NTFS系统。都了解NTFS文件系统的优势和好处,比起FAT和其他的什么HPFS文件系统有极大的改进,所以文件事务处理仅支持NTFS格式的文件系统。

事务性NTFS也称做TXF,只有最新的Windows系统才支持(WindowsVista\Windows7\WindowsServer2008\WindowsServer2008R2),所以在XP上就别测试了。[王清培版权所有,转载请给出署名]

在前几篇文章中都是使用的LTM本地事务管理器,然后进行事务范围类的多个持久资源登记自动事务提升为DTC类型的事务操作,由于DTC是非托管的实现,所以在分布式事务操作中会存在数据封送的性能损耗,MSDN也提倡尽量少用DTC处理,由于存在着很多不确定因素在遇到问题时比较棘手。但是在关键的时候还是需要这么用的,我们有必要去研究研究。

KTMDTCLTM三者的使用关系简单介绍

以前的理解思路和讲解的角度对于KTM来说是没多大关系的,但是由于他的出现我们有必要回归到原点进行重新的梳理来进行一个更加系统深入的理解,仅仅是理解;

在查询了大量的MSDN文档和对System.Transaction命名空间的仔细翻阅发现微软隐藏了很多.NET事务实现细节,比如System.Transaction.Oletx命名空间下的具体分布式协议的实现是没有任何技术文档看的,只能反编译自己看代码琢磨。

我们从LTM进行梳理,LTM是本地事务管理器那么他的存在只能在当前的托管AppDomain中,不能够夸远程处理,一旦跨远程处理负责传播的对象就要实现对本地事务的提升功能,包括WCF中的一系列的banding元素和事务感知型代码,都必须对事务进行管理,但是大部分的代码都是系统提供的。[王清培版权所有,转载请给出署名]

反编译看了部分代码,其中都会涉及到P\Invoke和COM\Interop之类的代码,凭自己的理解它的目的是启动IDTCTransaction接口,也就是COM接口。理解这一点对于我们下面的KTM操作非常有利。LTM要想进行DTC管理就必须通过OLE32.DLL进行COM接口的加载也就是我们托管的.NET类库里面的IDTCTransaction接口,看一下代码:

//  Describes a DTC transaction.
    [Guid("0fb15084-af41-11ce-bd2b-204c4f4f5020")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IDtcTransaction

 

该接口是向COM公开时的类型,用作于COM互操作使用的,需要通过该接口进行DTC的提升使用;为了验证理解是否正确我们来进行一个简单的测试,我们手动的通过System.Transaction.TransactionInterop类来获取非托管的IDTCTransaction接口,请看代码:

LTM事务:

public static void StartCopy()
  {
     using (TransactionScope transcope = new TransactionScope())
       {
           transcope.Complete();
        }
   }

 

这样的代码是不会提升为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

时间: 2024-09-20 16:56:25

使用KTM(内核事务管理器)进行文件事务处理的相关文章

spring事务管理器的源码和理解

以前说了大多的原理,今天来说下spring的事务管理器的实现过程,顺带源码干货带上. 其实这个文章唯一的就是带着看看代码,但是前提你要懂得动态代理以及字节码增强方面的知识(http://blog.csdn.net/xieyuooo/article/details/7624146),关于annotation在文章:http://blog.csdn.net/xieyuooo/article/details/8002321 也有说明,所以本文也就带着看看代码而已. 关于annotation这里就不说了

分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager

1 系列目录 分布式事务系列(开篇)提出疑问和研究过程 分布式事务系列(1.1)Spring事务管理器PlatformTransactionManager源码分析 分布式事务系列(1.2)Spring事务体系 分布式事务系列(2.1)分布式事务模型与接口定义 分布式事务系列(3.1)jotm的分布式案例 分布式事务系列(3.2)jotm分布式事务源码分析 分布式事务系列(4.1)Atomikos的分布式案例 2 jdbc事务 2.1 例子 public void save(User user)

lixa 0.5.35发布 一个事务管理器

LIXA(LIbre XA)是一个事务管理器,用于执行分布式事务处理的"XA规范"和"TX规范"(transaction demarcation),按照 X/Open CAE规范. lixa 0.5.35该版本支持移植到英特尔/AMD64位架构的GNU/Linux操作系统. 下载地址:http://sourceforge.net/projects/lixa/files/lixa/0.5.x/

lixa 0.7.3发布 一个事务管理器

LIXA(LIbre XA)是一个开源的XA事务管理器,用于执行分布式事务处理的"XA规范"和"TX规范"(transaction demarcation),遵循 X/Open CAE 规范. lixa 0.7.3该版本http://www.aliyun.com/zixun/aggregation/13387.html">WebSphere MQ7.1(CentOS 32位)已成功测试正确,作为由LIXA事务管理协调资源管理工作.lixa配置,一个新

lixa 0.5.33发布 一个事务管理器

lixa 0.5.33此版本附带了一些例子,显示LIXA如何用于协调PostgreSQL的Oracle数据库服务器和IBM DB2数据服务器的分布式事务. LIXA (LIbre XA) 是一个事务管理器,实现了分布式事务处理 XA 规范和 TX(transaction demarcation) 规范. 下载地址:http://sourceforge.net/projects/lixa/files/lixa/0.5.x/lixa-0.5.33.tar.gz/download

谈谈分布式事务之二:基于DTC的分布式事务管理模型[下篇]

[续上篇] 当基于LTM或者KTM的事务提升到基于DTC的分布式事务后,DTC成为了本机所有事务型资源 管理器的管理者:此外,当一个事务型操作超出了本机的范围,出现了跨机器的调用后,本机的DTC需要 于被调用者所在机器的DTC进行协助.上级对下级(包括本机DTC对本机所有资源管理器,以及上下级DTC )的管理得前提是下级在上级那里登记,即事务登记(Transaction Enlist).所有事务参与者,包括 所有资源管理器和事务管理器(即DTC)在进行了事务等级完成之后形成了一个树形的层级结构,

为什么配置的spring事务管理没有效果

问题描述 <?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/a

Spring与Hibernate整合事务管理的理解_java

在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据操作,然后提交事务,关闭事务,我们这样做的原因是因为Hibernate默认的事务自动提交是false,他是需要我们人为的手动提交事务,假如你不想每次都手动提交事务的话,你可以在hibernate.cfg.xml我文件中把它设置为事务自动提交: xml代码 <property name="def

Spring 事务管理高级应用难点剖析: 第 1 部分

Spring 的事务管理是被使用得最多的功能之一,虽然 Spring 事务管理已经帮助程序员将要做的事情减到了最小.但在实际开发中,如果使用不当,依然会造成数据连接泄漏等问题.本系列以实际应用中所碰到的各种复杂的场 景为着眼点,对这些应用的难点进行深度的剖析. DAO 和事务管理的牵绊 很少有使用 Spring 但不使用 Spring 事务管理器的应用,因此常常有人会问:是否用了 Spring,就一定要用 Spring 事务管理器,否则就无法进行数据的持久化操作呢?事务管理器和 DAO 是什么关