2017-02-20 54 views
2

保存中に例外が発生した場合、以下のコードで変更がロールバックされますか?EntityFrameworkトランザクション - 複数のテーブルに保存

using (SampleEntities context = new SampleEntities()) 
{ 
    //Code Omitted 

    context.EmpPercAdjustments.AddRange(pp); 
    context.SampleJobs.AddRange(sampleJobs); 

    context.SaveChanges(); 
} 

それとも

私はトランザクションを使用する必要がありますか?

using (SampleEntities context = new SampleEntities()) 
{ 
    //Code Omitted 

    using (System.Data.Entity.DbContextTransaction tranc = context.Database.BeginTransaction()) 
    { 
     try 
     { 
      context.EmpPercAdjustments.AddRange(pp); 
      context.SampleJobs.AddRange(sampleJobs); 
      context.SaveChanges(); 
      tranc.Commit(); 
     } 
     catch (Exception ee) 
     { 
      tranc.Rollback(); 
     } 
    } 
} 

他のものを使用する利点はありますか?

+0

試しましたか? –

+0

@CallumLiningtonはい私はそれを試した。何か例外がある場合、両方のコードロールバックのように見えます。 – ElectricRouge

+0

@ CallallLinington最初のテーブルでデータが正常に保存され、最初の例で2番目のテーブルに保存中に例外が発生した場合はどうなりますか?どのように私はそのシナリオをテストできますか? – ElectricRouge

答えて

3

はい正しくロールバックされます。

この場合、Entity Frameworkによってすでに作成されているトランザクションがあるため、明示的なトランザクションを実行する必要はありません。

context.Database.BeginTransaction()を呼び出してトランザクションを作成すると、f.e.このように単に挿入されたレコード、何かのIDを取得するには:この場合

using (SampleEntities context = new SampleEntities()) 
{ 
    using (System.Data.Entity.DbContextTransaction trans = context.Database.BeginTransaction()) 
    { 
     context.SampleJobs.Add(newJob); 
     context.SaveChanges(); 
     var jobId = newJob.Id; 
     //do other things, then commit or rollback 
     trans.Commit(); 
    } 
} 

を、SaveChanges()を呼び出した後、​​で行った変更が適用されます(そのデータベースを読み取ることができ、あなたの範囲に追加したオブジェクトのIDを生成)変更は唯一dirty writtenであるため、コミットまたはロールバックする必要があります。

明示的なトランザクションの定義は、コンテキストオブジェクトを変更できる複数のメソッドがあり、変更がすべてコミットされるかどうかを最終的に判断したい場合にも便利です。

+0

私はあなたのコメント '//他のことをする...'と非常にはっきりしていますが、ユーザがコミットしているか、ロールバックしていなければなりません。後で予期せぬ結果を招く可能性があるので、コミットされていないトランザクションは危険です。汚いセーブをしてから数秒後にロールバックすると、値をロールバックする可能性があります。または、おそらく何かに悪影響を及ぼさない別のコミットでこれを包み込むことができますが、復旧時に変なことが起こる可能性があります。 – djangojazz

+1

はい、そのようなトランザクションを常にコミットまたはロールバックする必要があります。しかし、そうしないと、コミットされていないtransオブジェクトを破棄するときにロールバックが呼び出されます(これは 'using'ブロックを残した後に実行されます)。 – tomassino

+0

面白いことはありません。テストコードを確認してください。 – djangojazz

関連する問題