4

内部の 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();
}
4

2 に答える 2

5

t3。t2 のスコープは t1 を抑制することであり、独自のアンビエントを作成することではないため、そこから選択するものは他にありません。したがって、最も内側のスコープには t3 だけがあり、他には何もありません。

t2 の場合RequireNew、t3 が t2 に結合するため、最も内側のスコープ アンビエントは t2 になります。

于 2012-10-16T13:43:27.550 に答える
4

注意: 抑制された 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"));
        }
    }

出力:

  • カウント = 1
  • 値 'Test1' = 0 を持っています
  • 値 'Test2' = 0 を持っています
  • 「Test1」を追加
  • 変更の保存 = 1
  • 「Test2」を追加
  • 変更の保存 = 1
  • カウント = 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"));
        }
    }

出力:

  • カウント = 0
  • 値 'Test1' = 0 を持っています
  • 値 'Test2' = 0 を持っています
  • 値 'Test3' = 0 を持っています
  • 「Test1」を追加
  • 変更の保存 = 1
  • 「Test2」を追加
  • 変更の保存 = 1
  • 「Test3」を追加
  • 変更の保存 = 1
  • カウント = 2
  • 値 'Test1' = 0 を持っています
  • 値は 'Test2' = 1
  • 値 'Test3' = 1 を持っています

ご覧のとおり、「scope3」がその変更をコミットするため、「scope」と「scope3」の間に関係はありません。

また、「scope2」は抑制されたスコープであるため、「scope2」はその変更をコミットします。

于 2015-07-29T12:51:17.340 に答える