Transactional File System (TxF)
Eintrag zuletzt aktualisiert am: 12.02.2011
Seit Windows NT 6.0 (Vista, Server 2008) unterstützt das Windows-
NTFS-
Dateisystem atomare
Transaktionen.
Transactional File System (alias "Transactional
NTFS", Abkürzung TxF) erlaubt auf Basis des
Kernel Transaction Manager (
KTM)
Transaktionen im
Dateisystem. Damit kann z.B. verhindert werden, das durch einen Programmabbruch während des Beschreibens einer Datei eine halbfertige oder inkonsistente Datei im
Dateisystem verbleibt. Auch kann erreicht werden, dass mehrere Dateien konsistent beschrieben werden.
Das TxF nutzt den
Kernel Transaction Managers (
KTM), der sich wiederum in dem schon seit langem verfügbaren
Microsoft Distributed Transaction Coordinator (
MSDTC) integriert. Damit kann man
Transaktionen schaffen, die
Dateisystem, Datenbanken und die Windows-
Registrierungsdatenbank (
Transactional Registry) umfassen. Auch Änderungen im
Dateisystem auf mehreren Computern kann man als
Transaktion abbilden.
Verfügbarkeit
TxF ist für lokale Dateien verfügbar seit
Windows Vista, für entfernte Dateien seit
Windows Server 2008.
Für TxF gibt es leider noch keine direkte Unterstützung im
.NET Framework. Die Programmierschnittstelle ist offiziell von Microsoft bisher nur auf C++-Ebene in der Kernel32.dll verfügbar (z.B. durch die Funktion CreateFileTransacted(), CopyFileTransacted(), DeleteFileTransacted(), etc.).
Es gibt aber als
Open Source-Bibliothek einen in C#-geschriebene
Wrapper-Bibliothek mit Namen "Transactional
NTFS Managed
Wrapper" (
http://code.msdn.microsoft.com/txfmanaged).
Damit kann man dann die elegante
Transaktionsunterstützung durch die .NET-Bibliothek
System.Transactions nutzen. Bei der Verwendung von
System.Transactions ist eine Instanz von
System.Transactions.TransactionScope zu erzeugen. Die
Transaktion gilt als erfolgreich abgeschlossen (Commit), wenn die Complete()-
Methode aufgerufen wird. Wird das TransactionScope vernichtet, ohne den Aufruf von Complete(), z.B. weil es zu einem Laufzeitfehler gekommen ist, gilt die
Transaktion als nicht erfolgreich (Abort). Alle Aktionen innerhalb zwischen der Erzeugung von TransactionScope und dem Commit/Abort werden automatisch Teil der
Transaktion, sofern es für diese Aktion einen
Transaktionsmanager gibt. Die Verwaltung der
Transaktion obliegt dem
MSDTC, einem Systemdienst von Windows, der gestartet sein muss.
Beispiel
Das folgende Beispiel zeigt die sehr elegante Verwendung von TransactionScope über eine using{}-Block in C# in einer
Methode der Geschäftslogik. Innerhalb des using{}-Blocks werden zwei
Methoden der
Datenzugriffsschicht aufgerufen (ReduzierePlatzAnzahl () und ErzeugeBuchung()). Außerdem erfolgt das Erstellen einer Protokolldatei im
NTFS-
Dateisystem. Nur wenn alle drei Aktionen erfolgreich waren, kommt es zum Aufruf vom Complete(). Nur dann werden die Veränderungen in der Datenbank und die erzeugte Datei im
Dateisystem bestandskräftig.
/// <summary>
/// Flugbuchung erstellen
/// </summary>
public string NewBuchung(int FlugNummer, int PassagierNummer)
{
try
{
string Buchungscode = FlugNummer.ToString() + "-" + PassagierNummer.ToString();
//
Transaktion, nur erfolgreich wenn Platzanzahl reduziert und Buchung erstellt!
Using (
System.Transactions.TransactionScope t = new
System.Transactions.TransactionScope())
{
// hier erfolgen Änderungen in Datenbanken über zwei
Methoden der
Datenzugriffsschicht
if (!Flug
DZS.ReduzierePlatzAnzahl(FlugNummer, 1)) return "Kein Platz auf diesem Flug vorhanden!";
if (!Buchungs
DZS.ErzeugeBuchung(PassagierNummer, FlugNummer)) return "Buchung nicht möglich!";
// Protokolldatei im
NTFS-
Dateisystem schreiben (als Teil der
Transaktion)
string Path = @"t:\buchungen\" + Buchungscode + ".txt";
File
Stream fs = TransactedFile.Open(Path,
System.IO.FileMode.CreateNew,
System.IO.FileAccess.Write,
System.IO.FileShare.None);
StreamWriter sw = new
StreamWriter(fs);
sw.WriteLine(DateTime.Now + ";" + Buchungscode + ";" + FlugNummer + ";" + PassagierNummer);
sw.Close();
fs.Close();
//
Transaktion abschließen
t.Complete();
// Buchungscode zurückgeben
return Buchungscode;
}
}
catch (
Exception ex)
{
return "Fehler: " + ex.Message;
}
}