天天看點

使用KTM(核心事務管理器)進行檔案事務處理

從資料庫到自定義資料總管都能參與到事務進行中來,在必要的時候保證資料的完整性,那麼我們缺一個類型的資源操作,當然您也許早就想問了,關于檔案系統的事務操作怎麼辦?那麼關于檔案的事務操作是否有成熟的解決方案了,這點在前幾年還真沒辦法,但是最近微軟已經釋出了關于事務性NTFS系統。都了解NTFS檔案系統的優勢和好處,比起FAT和其他的什麼HPFS檔案系統有極大的改進,是以檔案事務處理僅支援NTFS格式的檔案系統。

事務性NTFS也稱做TXF,隻有最新的Windows系統才支援(WindowsVista\Windows7\WindowsServer2008\WindowsServer2008R2),是以在XP上就别測試了。[王清培版權所有,轉載請給出署名]

在前幾篇文章中都是使用的LTM本地事務管理器,然後進行事務範圍類的多個持久資源登記自動事務提升為DTC類型的事務操作,由于DTC是非托管的實作,是以在分布式事務操作中會存在資料封送的性能損耗,MSDN也提倡盡量少用DTC處理,由于存在着很多不确定因素在遇到問題時比較棘手。但是在關鍵的時候還是需要這麼用的,我們有必要去研究研究。

KTM、DTC、LTM三者的使用關系簡單介紹

以前的了解思路和講解的角度對于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接口,看一下代碼:

該接口是向COM公開時的類型,用作于COM互操作使用的,需要通過該接口進行DTC的提升使用;為了驗證了解是否正确我們來進行一個簡單的測試,我們手動的通過System.Transaction.TransactionInterop類來擷取非托管的IDTCTransaction接口,請看代碼:

LTM事務:

這樣的代碼是不會提升為DTC管理的,我們加一行代碼:

先解釋一下TransactionInterop類的作用,來自MSDN的說明:

“促進System.Transactions 和以前編寫的用于與 MSDTC、COM+ 或 System.EnterpriseServices 進行互動的元件之間的互動。無法繼承此類。”

其實該類主要用來對早期的分布式事務技術進行互操作,比如用來擷取DTC相關的COM對象或者用來進行自定義的事務傳播,對于複雜的Oletx(Windows平台的二進制通訊協定)協定,我們不需要關心太多核心的東西就能進行分布式事務的傳遞,這裡可能Remoting有這個需求了。[王清培版權所有,轉載請給出署名]

利用TransactionInterop.GetDtcTransaction方法确實能擷取到DTC事務接口。

圖1:

使用KTM(核心事務管理器)進行檔案事務處理

有了TransactionInterop類,我們後面的擴充就友善多了。

由于KTM是屬于非托管實作,作業系統提供了檔案操作的事務性API方法:

非事務處理 API

事務處理 API

CreateFile

CreateFileTransacted

CopyFileEx

CopyFileTransacted

MoveFileWithProgress

MoveFileTransacted

DeleteFile

DeleteFileTransacted

CreateHardLink

CreateHardLinkTransacted

CreateSymbolicLink

CreateSymbolicLinkTransacted

CreateDirectoryEx

CreateDirectoryTransacted

RemoveDirectory

RemoveDirectoryTransacted

 通過封裝這些方法就能夠實作事務性的檔案操作,目前.NET沒有封裝成熟的類庫給我們使用,估計在後期的新版本類庫中可能會提供。

那麼我們如何使用KTM事務處理呢,很幸運的是通過MSND的連接配接我們能夠擷取到微軟的事務開發人員編寫的源碼,下載下傳位址為:

<a href="http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TxF2007_07.exe">http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TxF2007_07.exe</a>

 源碼都是通過對上面的API進行封裝的,裡面涉及到了很多關于内部API和COM之間的通訊細節,我們可以看看老外寫的代碼是複雜,也是我們學習的榜樣。

 上面我們說過隻要誇目前應用程式域的事務處理就會自動提升為DTC事務,對于API的調用已經是出于互操作類型的,目前已經出于遠端調用,DTC已經具有與托管域的互動實作,是以我們隻有通過DTC進入KTM進行操作。這也是MSDN官方的解釋。

圖2:

使用KTM(核心事務管理器)進行檔案事務處理

我們來看一個簡單的例子,該例子實作對檔案的事務性删除操作。

例子1:

我簡單的寫了一段測試代碼,經過測試是OK的。KTM能很好的結合DTC、LTM進行混合的事務處理,對于我們上面引入的疑問現在能完美的解決了。