Which Transaction does the inner TransactionScope take as ambient transaction ?
using ( var t1 = new TransactionScope( TransactionScopeOption.Required ) )
{
//MyStuff
using ( var t2 = new TransactionScope( TransactionScopeOption.Suppress) )
{
//MyStuff
using ( var t3 = new TransactionScope( TransactionScopeOption.Required) )
{
//Mystuff
t3.Complete();
}
t2.Complete();
}
t1.Complete();
}
t3. There is nothing else to choose from there, since the scope of t2 is to supress t1, not to create it's own ambient. Therefore at the innermost scope there is only t3 and nothing else.
If t2 would be RequireNew
then the innermost scope ambient would be t2 since t3 would join t2.
Keep in mind: a suppressed TransactionScope do not need to "complete"
There is no transaction.
For example you could do this here:
static void TestMethod()
{
using (Model1 ctx = new Model1())
{
Console.WriteLine("Count = {0}", ctx.Test.Count());
Console.WriteLine("Has Value 'Test1' = {0}", ctx.Test.Count(x => x.Value == "Test1"));
Console.WriteLine("Has Value 'Test2' = {0}", ctx.Test.Count(x => x.Value == "Test2"));
}
using (Transactions.TransactionScope scope = new Transactions.TransactionScope())
{
using (Model1 ctx = new Model1())
{
ctx.Test.Add(new Test { Value = "Test1" });
Console.WriteLine("Add 'Test1'");
Console.WriteLine("SaveChanges = {0}", ctx.SaveChanges());
}
using (Transactions.TransactionScope scope2 = new Transactions.TransactionScope(Transactions.TransactionScopeOption.Suppress))
{
using (Model1 ctx = new Model1())
{
ctx.Test.Add(new Test { Value = "Test2" });
Console.WriteLine("Add 'Test2'");
Console.WriteLine("SaveChanges = {0}", ctx.SaveChanges());
}
}
}
using (Model1 ctx = new Model1())
{
Console.WriteLine("Count = {0}", ctx.Test.Count());
Console.WriteLine("Has Value 'Test1' = {0}", ctx.Test.Count(x => x.Value == "Test1"));
Console.WriteLine("Has Value 'Test2' = {0}", ctx.Test.Count(x => x.Value == "Test2"));
}
}
Output:
That means every query in a suppressed scope cannot rollback by just disposing the scope.
But if you do this:
static void TestMethod()
{
using (Model1 ctx = new Model1())
{
Console.WriteLine("Count = {0}", ctx.Test.Count());
Console.WriteLine("Has Value 'Test1' = {0}", ctx.Test.Count(x => x.Value == "Test1"));
Console.WriteLine("Has Value 'Test2' = {0}", ctx.Test.Count(x => x.Value == "Test2"));
Console.WriteLine("Has Value 'Test3' = {0}", ctx.Test.Count(x => x.Value == "Test3"));
}
using (Transactions.TransactionScope scope = new Transactions.TransactionScope())
{
using (Model1 ctx = new Model1())
{
ctx.Test.Add(new Test { Value = "Test1" });
Console.WriteLine("Add 'Test1'");
Console.WriteLine("SaveChanges = {0}", ctx.SaveChanges());
}
using (Transactions.TransactionScope scope2 = new Transactions.TransactionScope(Transactions.TransactionScopeOption.Suppress))
{
using (Model1 ctx = new Model1())
{
ctx.Test.Add(new Test { Value = "Test2" });
Console.WriteLine("Add 'Test2'");
Console.WriteLine("SaveChanges = {0}", ctx.SaveChanges());
}
using (Transactions.TransactionScope scope3 = new Transactions.TransactionScope())
{
using (Model1 ctx = new Model1())
{
ctx.Test.Add(new Test { Value = "Test3" });
Console.WriteLine("Add 'Test3'");
Console.WriteLine("SaveChanges = {0}", ctx.SaveChanges());
}
scope3.Complete();
}
}
}
using (Model1 ctx = new Model1())
{
Console.WriteLine("Count = {0}", ctx.Test.Count());
Console.WriteLine("Has Value 'Test1' = {0}", ctx.Test.Count(x => x.Value == "Test1"));
Console.WriteLine("Has Value 'Test2' = {0}", ctx.Test.Count(x => x.Value == "Test2"));
Console.WriteLine("Has Value 'Test3' = {0}", ctx.Test.Count(x => x.Value == "Test3"));
}
}
Output:
You can see: there is no relation between "scope" and "scope3", because "scope3" commit its changes.
Also "scope2" commit its changes, because "scope2" is a suppressed scope.
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