Looking at the code :
class MyClass { public static int g=1;}
using (TransactionScope tsTransScope = new TransactionScope())
{
//Do stuff here
MyClass.g=999;
tsTransScope.Complete();
}
Looking at the "Do stuff here" section : What type of objects can I write in there so they can be Transactionable ?. I already know that I can write ADO commands and they will be rollback/commited when neccesary. But via C#
POV : what implementation should a Class has to have in order to be Transactionable ( implementing some interface or something ?)
If it is a TransactionScope
as it called , inside a using
clause (which is try + finally) , The logic says that if there is a rollback : MyClass.g
should get BACK its value of 1. however. this is not happening.
So I guess it is related to the first question. How can I make MyClass Transactionable ?
You should implement System.Transactions.IEnlistmentNotification
interface, this article and this may help you
For ready-made transactional in-memory storage, there is (Software transactional memory), and STM.NET it is not a final stuff, but Microsoft is working on it!
A small example:
using System.IO;
using System.Text;
using System.Transactions;
namespace Sakher.Transactions
{
public class TsansactionalFileWriter
{
private FileTransactionEnlistment fileTransactionEnlistment = new FileTransactionEnlistment();
public TsansactionalFileWriter(string filePath)
{
fileTransactionEnlistment.FilePath = filePath;
Transaction.Current.EnlistVolatile(fileTransactionEnlistment, EnlistmentOptions.None);
}
public void AppendText(string text)
{
fileTransactionEnlistment.Content.Append(text);
}
public void WriteAllText(string text)
{
fileTransactionEnlistment.Content = new StringBuilder(text);
}
}
public class FileTransactionEnlistment : IEnlistmentNotification
{
public string FilePath { get; set; }
public StringBuilder Content { get; set; }
public FileTransactionEnlistment()
{
Content = new StringBuilder();
}
public void Commit(Enlistment enlistment)
{
File.WriteAllText(FilePath, Content.ToString());
}
public void InDoubt(Enlistment enlistment)
{
}
public void Prepare(PreparingEnlistment preparingEnlistment)
{
//You can create the file here
preparingEnlistment.Prepared();
}
public void Rollback(Enlistment enlistment)
{
//Do ssomething when the transaction is rolled-back (You may delete the file if you have created it!)
}
}
}
Consuming the code:
using (TransactionScope tr = new TransactionScope())
{
TsansactionalFileWriter writer = new TsansactionalFileWriter("c:\\myFile.txt");
writer.AppendText("sdfgssdfgsdf");
tr.Complete();
}
* EDTI : ADDED G KEEPER FOR ROYI :) *
using System.Transactions;
namespace Sakher.Transactions
{
public class Royi_s_gReturnerClass
{
private GReturnerEnlistment fileTransactionEnlistment = new GReturnerEnlistment();
public Royi_s_gReturnerClass()
{
Transaction.Current.EnlistVolatile(fileTransactionEnlistment, EnlistmentOptions.None);
}
}
public class GReturnerEnlistment : IEnlistmentNotification
{
public int GOldValue { get; set; }
public GReturnerEnlistment()
{
GOldValue = MyClass.g;
}
public void Commit(Enlistment enlistment)
{
}
public void InDoubt(Enlistment enlistment)
{
}
public void Prepare(PreparingEnlistment preparingEnlistment)
{
preparingEnlistment.Prepared();
}
public void Rollback(Enlistment enlistment)
{
MyClass.g = GOldValue;
}
}
}
Your code will be:
class MyClass { public static int g=1;}
using (TransactionScope tsTransScope = new TransactionScope())
{
Royi_s_gReturnerClass returner = new Royi_s_gReturnerClass();
//Do stuff here
MyClass.g=999;
tsTransScope.Complete();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With