Soru Varlık Framework 6 işlem geri alma


EF6 ile birlikte kullanılabilecek yeni bir işleminiz var:

using (var context = new PostEntityContainer())
        {
            using (var dbcxtransaction = context.Database.BeginTransaction())
            {
                try
                {
                    PostInformation NewPost = new PostInformation()
                    {
                        PostId = 101,
                        Content = "This is my first Post related to Entity Model",
                        Title = "Transaction in EF 6 beta"
                    };
                    context.Post_Details.Add(NewPost);
                    context.SaveChanges();
                    PostAdditionalInformation PostInformation = new PostAdditionalInformation()
                    {
                        PostId = (101),
                        PostName = "Working With Transaction in Entity Model 6 Beta Version"
                    };

                    context.PostAddtional_Details.Add(PostInformation);
                    context.SaveChanges();

                    dbcxtransaction.Commit();
                }
                catch
                {
                    dbcxtransaction.Rollback();
                }
            }
        }

Geri dönüşler, işler yanlara giderken gerçekten gerekli midir? Merak ediyorum, çünkü Commit açıklaması şöyle diyor: "Alttaki mağaza işlemlerini yürütür."

Geri Alma açıklamasında ise: "Alttaki mağaza işlemini geri alır."

Bu beni meraklandırıyor çünkü bana Commit'in çağrılmaması durumunda, daha önce çalıştırılan komutların saklanmayacağını (ki bu bana mantıklı geliyor) bakıyor. Ama durum böyleyse, Geri Alma işlevini çağırmanın nedeni ne olurdu? EF5'te, bana mantıklı görünen bir Rollback fonksiyonuna (sadece bir Complete) sahip olmayan TransactionScope'u kullandım. MS DTC nedeniyle, TransactionScope'u artık kullanamıyorum, ama aynı zamanda yukarıdaki örnekte olduğu gibi bir try catch'u kullanamıyorum (yani sadece Commit'e ihtiyacım var).


65
2018-03-18 17:18


Menşei


Okudun mu sql'de işlemler? EF bunu taklit etmeye çalışır. AFAIK, eğer sql'de bir işlem yapmazsanız, geri alınır. - gunr2171
Ayrıca bkz. bu soru. - gunr2171
Evet, SQL'in işlemlerini biliyorum. EF'in ne yaptığını merak ettim, ama eğer taklit ederse, mantıklı. Etrafında çalışabilir miyim göreceğim. Teşekkür ederim! - The Cookies Dog
SaveChanges () her zaman, bir istisna meydana gelirse geri alınacak bir işlemde olur. Durumunuzda bunu elle işlemeye gerek yoktur (bu durumda, ilk önce tüm varlıkları eklemek daha iyi olacaktır. SaveChanges sadece bir kere). - Pawel
Her ikisi de başarısız olmadığında, yalnızca SaveChanges öğesinden kaydedilecek öğeleri istiyorum, yani, her ikisi de tek bir işlem yapmam gerekiyor. - The Cookies Dog


Cevaplar:


Aramana gerek yok Rollback el ile kullandığınız için using Beyan.

DbContextTransaction.Dispose Yöntemin sonunda çağrılacak using blok. Ve işlem başarılı bir şekilde işlenmezse (çağrılan veya istisnalarla karşılaşılmadıysa) işlemi otomatik olarak geri alır. Aşağıdaki kaynak kodu SqlInternalTransaction.Dispose yöntem (DbContextTransaction.Dispose sonunda SqlServer sağlayıcısı kullanırken ona yetki verilecektir):

private void Dispose(bool disposing)
{
    // ...
    if (disposing && this._innerConnection != null)
    {
        this._disposing = true;
        this.Rollback();
    }
}

Görüyorsun, eğer kontrol eder _innerConnection eğer değilse, null değildir, işlemin geri alınması (eğer taahhüt edilirse, _innerConnection boş olacak). Bakalım ne Commit yapar:

internal void Commit() 
{
    // Ignore many details here...

    this._innerConnection.ExecuteTransaction(...);

    if (!this.IsZombied && !this._innerConnection.IsYukonOrNewer)
    {
        // Zombie() method will set _innerConnection to null
        this.Zombie();
    }
    else
    {
        this.ZombieParent();
    }

    // Ignore many details here...
}

internal void Zombie()
{
    this.ZombieParent();

    SqlInternalConnection innerConnection = this._innerConnection;

    // Set the _innerConnection to null
    this._innerConnection = null;

    if (innerConnection != null)
    {
        innerConnection.DisconnectTransaction(this);
    }
}

96
2017-07-06 03:47





Her zaman SQL Server'ı EF ile kullanacağınız sürece, geri alma yöntemini çağırmak için catch'u açıkça kullanmaya gerek yoktur. Herhangi bir özel durum için otomatik olarak geri alma bloğunun kullanılmasına izin verilmesi her zaman işe yarar.

Bununla birlikte, Entity Framework bakış açısıyla düşündüğünüzde, tüm örneklerin, işlemi Geri Alma ile ilgili açık çağrıyı neden kullandığını görebilirsiniz. EF'ye göre, veritabanı sağlayıcısı keyfi ve takılabilirdir ve sağlayıcı, MySQL veya EF sağlayıcı uygulaması olan herhangi bir başka veritabanı ile değiştirilebilir. Bu nedenle, EF açısından bakıldığında, hizmet sağlayıcının, atılan işlemi otomatik olarak geri alacağının bir garantisi yoktur, çünkü EF, veritabanı sağlayıcısının uygulanmasını bilmemektedir.

Bu yüzden, en iyi uygulama olarak, EF belgeleri, bir gün içinde sağlayıcıları elden çıkarmayı otomatik olarak geri almayan bir uygulamaya dönüştürmeniz durumunda, açıkça Geri Almanızı önerir.

Benim düşünceme göre, iyi ve iyi yazılmış herhangi bir sağlayıcı, işlemi otomatik olarak elden çıkarır, bu nedenle kullanım bloğu içindeki her şeyi bir try-catch-rollback ile sarmak için ek çaba fazladır.


18
2018-03-07 13:44



Bu anlayış için teşekkürler. Ben kodun içine dove ve sen Mouhong Lin tarafından belirtilen SqlInternalTransaction çağırır SqlTransaction içinde geçersiz kılan soyut sınıf DbTransaction's Dispose sonunda. - ShawnFumo


  1. Bir örnek oluşturmak için bir 'using' bloğu yazdığınızdan işlem, Rollback işlevini belirtmenize gerek yoktur otomatik olarak geri alınacağından beri açıkça imha edildiğinde).
  2. Ama eğer bir kullanma bloğu olmadan onu başlatırsanız, o zaman Bir istisna durumunda işlemi geri almak için gereklidir (tam olarak bir yakalama bloğu) ve daha fazlası için null bir çek ile sağlam kod. BeginTransaction'ın çalışması işlemden farklıdır kapsam (tüm operasyonlar için sadece tam bir fonksiyona ihtiyaç duyar) başarıyla tamamlandı). Bunun yerine, çalışmasına benzer Sql işlemleri.

3
2017-07-09 10:06