Now a days we are using System.Transactions.TransactionScope object for handle transaction. But transaction scope current limitation is that it can not work with filesystem. scenario  like I need to

i)   Add a record to database

                               ii)  Delete a file from FileSystem

                              iii)   Need to write Xml File

That needs to work as a unit (batch). If one task failed then while task need to failed.  If we carefully see that in the tasklist we see filedelete, xmlupdate type complex things is there which is not easy to roolback and we can not use Transaction scope as a tool to handle this scenario due to lacking of file system handle. But I need to use TransactionScope in this scenario because we all know how to use Transactionscope and it is very easy. But how

System.Transactions.IEnlistmentNotification interface come to save life. It is actually commit notification callback for dotnet transaction manager. It has 4 members

1)      Void Commit(Enlistment)

2)      Void InDoubt(Enlishment)

3)      Void Prepare(PreparingEnlishment)

4)      Void Rollback(Enlishment)

Detail explanation is in msdn referce. We can see there.

Now see the code sample that use this   

 

   public class  TxFileManager : IEnlistmentNotification
    {
       //Keep files last state for handle rollback operation
        public TxFileManager()
        {
            if (File.Exists("d:\\xyz123.txt"))
                File.Delete("d:\\xyz123.txt");
 
            var f = new FileInfo("d:\\xyz.txt");
            f.CopyTo("d:\\xyz123.txt");
 
            var xml = XDocument.Load("d:\\data.xml", LoadOptions.None);
            xml.Save("d:\\xyz123.xml");
        }
    
        public void Commit(Enlistment enlistment)
        {
            Console.WriteLine("Commit notification received");
            enlistment.Done();
        }
 
        public void InDoubt(Enlistment enlistment)
        {
            Console.WriteLine("In doubt notification received");            
            enlistment.Done();
        }
 
        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            Console.WriteLine("Prepare notification received");
            preparingEnlistment.Prepared();         
        }
 
        //back state to changed files
        public void Rollback(Enlistment enlistment)
        {
            File.Copy("d:\\xyz123.txt", "d:\\xyz.txt");
            var xml = XDocument.Load("d:\\xyz123.xml", LoadOptions.None); 
            xml.Save("d:\\data.xml");                            
            enlistment.Done();
        }
    }//end class
 
 
   class Program
    {
        static void Main(string[] args)
        {
           //using file operations inside transction scope
            using (var scope = new TransactionScope())
            {
               //Db Operation
                Db.ExecuteQuery("DELETE FROM Table1 WHERE Id = 100");
 
               //Register for Notification
                var obj = new TxFileManager();
                Transaction.Current.EnlistVolatile(obj, EnlistmentOptions.None);
 
                //Delete FileOpeartion 
                File.Delete("d:\\xyz.txt");
 
                //Xml Update Operation
                var xml = XDocument.Load("d:\\data.xml", LoadOptions.None);
                XElement el = xml.Element("teacher");
                el.SetElementValue("id", "100");
                el.Save("d:\\data.xml");
 
                //scope.Complete(); //We can comment this line for rollback test
            }
            Console.Read();
        }
    }

Code Explanation:

We create a  TxFileManager which implement IEnlistmentNotification and use it from transactionscope. Actually register it

               var obj = new TxFileManager();

               Transaction.Current.EnlistVolatile(obj, EnlistmentOptions.None);

For notification purpose. In TxFile Constructor  which files we need to store last state is captured and when rollback is required that time we replace those from that place(actually it is manual logic which I executed by the transactionscope object). That way we can use TransactionScope and overcome its limitation.

NB. File state back algorithm might be difference based on senario, performace or some other requirement, But main thing is that it need to handle manually for windows 2003 server. I see on net that in future microsoft implement IEnlistmentNotification interface for its file system object. So I guess in futre TransactionSope can handle it automatically. Means we need to write thouse types of code for future :) 

Add new comment