{"id":572,"date":"2010-05-18T22:20:04","date_gmt":"2010-05-18T20:20:04","guid":{"rendered":"http:\/\/dev.bratched.fr\/fr\/transactional-ntfs-partie-12\/"},"modified":"2010-05-18T22:20:04","modified_gmt":"2010-05-18T20:20:04","slug":"transactional-ntfs-partie-1","status":"publish","type":"post","link":"https:\/\/bratched.com\/fr\/2010\/05\/18\/transactional-ntfs-partie-1\/","title":{"rendered":"Transactional NTFS (partie 1\/2)"},"content":{"rendered":"<h1>Transactional NTFS et DotNet<\/h1>\n<p>Microsoft introduit un concept int\u00e9ressant \u00e0 partir des versions de Windows Vista et Server 2008.<br \/>\nCette nouveaut\u00e9 est appel\u00e9e <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363764%28VS.85%29.aspx\" rel=\"nofollow\">Transactional NTFS<\/a> (TxF).<br \/>\nElle permet aux d\u00e9veloppeurs d\u2019\u00e9crire des fonctions d\u2019Entr\u00e9e\/Sortie garantissant le succ\u00e8s complet ou le rejet complet en cas d\u2019erreur d\u2019un ensemble d\u2019op\u00e9rations.<\/p>\n<p>Malheureusement il n\u2019existe pas de classe DotNet(au moins jusqu\u2019\u00e0 la version 3.5 SP1) permettant de manipuler simplement ce type d\u2019op\u00e9rations.<\/p>\n<p>Pour manipuler ces op\u00e9rations, nous avons besoin de passer par le P\/Invoke pour utiliser ces fonctions :<\/p>\n<p><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa366011%28VS.85%29.aspx\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">CreateTransaction<\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa366001%28VS.85%29.aspx\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">CommitTransaction<\/a>, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa366366%28VS.85%29.aspx\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">RollbackTransaction<\/a> et <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363916%28VS.85%29.aspx\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">DeleteFileTransacted<\/a><\/p>\n<p><!--more--><\/p>\n<div id=\"scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:05ee2d52-4b2c-4097-9af7-12cf99277e07\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;padding: 0px;float: none\">\n<pre>class Win32Native\n{\n   [StructLayout(LayoutKind.Sequential)]\n   public struct SECURITY_ATTRIBUTES\n   {\n       int nLength;\n       IntPtr lpSecurityDescriptor;\n       int bInheritHandle;\n   }\n\n   [DllImport(\"ktmw32.dll\", SetLastError = true, CharSet = CharSet.Auto)]\n   public static extern SafeFileHandle CreateTransaction\n    \u00a0(SECURITY_ATTRIBUTES securityAttributes\n      , IntPtr guid, int options, int isolationLevel, int isolationFlags, \n      int milliSeconds, string description);\n\n   [DllImport(\"ktmw32.dll\", SetLastError = true, CharSet = CharSet.Auto)]\n   public static extern bool CommitTransaction(SafeFileHandle transaction);\n\n   [DllImport(\"ktmw32.dll\", SetLastError = true, CharSet = CharSet.Auto)]\n   public static extern bool RollbackTransaction(SafeFileHandle transaction);\n\n   [DllImport(\"kernel32.dll\", SetLastError = true, CharSet = CharSet.Auto)]\n   public static extern bool DeleteFileTransacted\n     (string filename, SafeFileHandle transaction);\n}<\/pre>\n<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http:\/\/dunnhq.com --><\/p>\n<\/div>\n<p>Notez que j\u2019utilise <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.win32.safehandles.safefilehandle.aspx\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">SafeFileHandle<\/a> dans la signature des m\u00e9thodes \u00e0 la place de <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.intptr%28VS.71%29.aspx\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">IntPtr<\/a> pour les ancienne ressources non manag\u00e9es afin de garantir que les \u00e9l\u00e9ments seront bien lib\u00e9r\u00e9s m\u00eame si l\u2019application doit s\u2019arr\u00eater.<\/p>\n<p>L\u2019\u00e9tape suivante est la d\u00e9finition d\u2019une classe permettant d\u2019appeler simplement les fonctions d\u00e9clar\u00e9es.<\/p>\n<div id=\"scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:469b910e-7828-4a45-9ab2-34dd560e363c\" class=\"wlWriterEditableSmartContent\" style=\"margin: 0px;padding: 0px;float: none\">\n<pre> public class FileManager : IDisposable\n{\n   private bool _commited = false;\n   private SafeFileHandle _tx = null;\n\n   public FileManager()\n   {\n       _tx = Win32Native.CreateTransaction\n         (new Win32Native.SECURITY_ATTRIBUTES(), IntPtr.Zero\n         , 0, 0, 0, 0, null);\n   }\n\n   public bool DeleteFile(string filename)\n   {\n       return Win32Native.DeleteFileTransacted\n         (filename, _tx);\n   }\n\n   public void Commit()\n   {\n       if (Win32Native.CommitTransaction(_tx))\n           _commited = true;\n   }\n\n   private void Rollback()\n   {\n       Win32Native.RollbackTransaction(_tx);\n   }\n\n   protected virtual void Dispose(bool disposing)\n   {\n       if (disposing)\n       {\n           if (!_commited)\n           {\n               Rollback();\n           }\n       }\n   }\n\n   public void Dispose()\n   {\n       Dispose(true);\n   }\n}<\/pre>\n<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http:\/\/dunnhq.com --><\/p>\n<\/div>\n<h1>Exemple avec la suppression de 2 fichiers<\/h1>\n<p>&nbsp;<\/p>\n<p>Supposons que nous devons supprimer automatiquement 2 fichiers. Les 2 fichiers doivent \u00eatre supprim\u00e9s en m\u00eame temps. Si un des 2 fichiers ne peut pas \u00eatre supprim\u00e9, les 2 fichiers doivent \u00eatre conserv\u00e9s.<\/p>\n<div id=\"scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:9169fafe-54c8-4c20-a946-a84bf4b4635c\" class=\"wlWriterSmartContent\" style=\"margin: 0px;padding: 0px;float: none\">\n<pre>    using (FileManager manager = new FileManager())\n    {\n        manager.DeleteFile(\"file1.txt\");\n        Console.WriteLine(\"file1.txt is marked for deletion in current transaction. Press Enter...\");\n        Console.ReadLine();\n\n        \/\/throw new Exception(\"something very bad happens here\");\n\n        manager.DeleteFile(\"file2.txt\");\n        Console.WriteLine(\"file2.txt is marked for deletion in current transaction.\");\n\n        manager.Commit();\n    }\n<\/pre>\n<\/div>\n<p>La m\u00e9thode <strong>DeleteFile<\/strong> marque le fichier pour la suppression dans le transaction courante, mais ne la supprimera uniquement si la m\u00e9thode Commit est appel\u00e9e.<\/p>\n<p>Gr\u00e2ce \u00e0 TFX et les transactions distribu\u00e9es, les op\u00e9rations sur les fichiers et les op\u00e9rations SQL peuvent s\u2019effectuer dans une m\u00eame op\u00e9ration.<\/p>\n<p>Dans la 2\u00e8me partie, nous verrons comment utiliser la fonction <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa363859%28VS.85%29.aspx\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">CreateFileTransacted<\/a> pour traiter de fa\u00e7on unique la lecture et l\u2019\u00e9criture d\u2019un fichier.<\/p>\n<div class=\"clearfix\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Transactional NTFS et DotNet Microsoft introduit un concept int\u00e9ressant \u00e0 partir des versions de Windows Vista et Server 2008. Cette nouveaut\u00e9 est appel\u00e9e Transactional NTFS (TxF). Elle permet aux d\u00e9veloppeurs d\u2019\u00e9crire des fonctions d\u2019Entr\u00e9e\/Sortie garantissant le succ\u00e8s complet ou le rejet complet en cas d\u2019erreur d\u2019un ensemble d\u2019op\u00e9rations. Malheureusement il n\u2019existe pas de classe DotNet(au [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34],"tags":[18,45],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts\/572"}],"collection":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/comments?post=572"}],"version-history":[{"count":0,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts\/572\/revisions"}],"wp:attachment":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/media?parent=572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/categories?post=572"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/tags?post=572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}