嵌套的Transactionscope,必需 - >抑制 - >需要

时间:2012-10-16 13:34:15

标签: c# .net sql-server transactions transactionscope

内部TransactionScope将哪个事务作为环境事务处理?

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();
}

2 个答案:

答案 0 :(得分:4)

T3。没有别的选择,因为t2的范围是压制t1,而不是创建它自己的环境。因此,在最里面的范围内,只有t3,没有别的。

如果t2为RequireNew,那么最里面的范围环境将为t2,因为t3将加入t2。

答案 1 :(得分:3)

请记住:被抑制的TransactionScope不需要“完成”

没有交易。

例如,您可以在此处执行此操作:

    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"));
        }
    }

输出:

  • Count = 1
  • 值'Test1'= 0
  • 值'Test2'= 0
  • 添加'Test1'
  • SaveChanges = 1
  • 添加'Test2'
  • SaveChanges = 1
  • Count = 1
  • 值'Test1'= 0
  • 值'Test2'= 1

这意味着只有处理范围才能回滚抑制范围内的每个查询。

但如果你这样做:

    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"));
        }
    }

输出:

  • Count = 0
  • 值'Test1'= 0
  • 值'Test2'= 0
  • 值'Test3'= 0
  • 添加'Test1'
  • SaveChanges = 1
  • 添加'Test2'
  • SaveChanges = 1
  • 添加'Test3'
  • SaveChanges = 1
  • Count = 2
  • 值'Test1'= 0
  • 值'Test2'= 1
  • 有值'Test3'= 1

你可以看到:“scope”和“scope3”之间没有关系,因为“scope3”提交了它的更改。

同样“scope2”提交其更改,因为“scope2”是一个被抑制的范围。