NHibernate ISession Flush: Nerede ve ne zaman kullanılır ve neden?


187

Beni iyice karıştı şeylerden biri kullanılmasıdır session.Flushile birlikte, session.Commitve session.Close.

Bazen session.Closeişe yarar, örneğin, ihtiyacım olan tüm değişiklikleri yapar. Ben bir işlem veya birkaç oluşturur / güncellemeler / siler ile bir iş birimi varsa, taahhüt kullanmanız gerektiğini biliyorum, böylece bir hata oluşursa geri almayı seçebilirsiniz.

Ama bazen gerçekten arkasındaki mantıktan rahatsız oluyorum session.Flush. session.SaveOrUpdate()Bir sifon izlediğin örnekleri gördüm , ama Sifonu kaldırdığımda yine de iyi çalışıyor. Bazen Flush deyiminde oturumun zaman aşımına uğradığını söyleyerek hatalarla karşılaşıyorum ve kaldırılması bu hatayla karşılaşmamamı sağladı.

Flush'ın nerede veya ne zaman kullanılacağına dair iyi bir rehber var mı? Bunun için NHibernate belgelerine baktım, ancak yine de basit bir cevap bulamıyorum.

Yanıtlar:


236

Kısaca:

  1. Her zaman işlemleri kullan
  2. Kullanmayın Close(), bunun yerine çağrılarınızı ISessionbir usingifadenin içine sarın veya ISession'ınızın yaşam döngüsünü başka bir yerde yönetin .

Gönderen belgeler :

Zaman zaman ISessionADO.NET bağlantısının durumunu bellekte tutulan nesnelerin durumu ile senkronize etmek için gereken SQL deyimlerini yürütür. Bu işlem, yıkama, varsayılan olarak aşağıdaki noktalarda gerçekleşir

  • Bazı etkinleştirilmelerinde gelen Find()veyaEnumerable()
  • itibaren NHibernate.ITransaction.Commit()
  • itibaren ISession.Flush()

SQL ifadeleri aşağıdaki sırayla verilir

  1. tüm varlık eklemeleri, aynı sırayla karşılık gelen nesneler kullanılarak kaydedildi ISession.Save()
  2. tüm varlık güncellemeleri
  3. tüm koleksiyon silme işlemleri
  4. tüm koleksiyon öğesi silme, güncelleme ve ekleme işlemleri
  5. tüm koleksiyon eklemeleri
  6. tüm varlık silmeleri, aynı sırayla karşılık gelen nesneler kullanılarak silindi ISession.Delete()

(Bunun bir istisnası, yerel kimlik oluşturma kullanan nesnelerin kaydedildiklerinde eklenmesidir.)

Açıklık dışında Flush(), Oturumun ADO.NET çağrılarını ne zaman yürüteceği konusunda kesinlikle hiçbir garanti yoktur, yalnızca yürütüldükleri sıra . Ancak, NHibernate ISession.Find(..)yöntemlerin asla eski verileri döndürmeyeceğini garanti eder ; ne de yanlış verileri döndürmezler.

Yıkama işleminin daha az sıklıkta gerçekleşmesi için varsayılan davranışı değiştirmek mümkündür. FlushModeSadece zaman taahhüt de aynı hizada (ve NHibernate yalnızca: Sınıf üç farklı mod tanımlar ITransaction, API kullanılır) floş otomatik rutin veya sürece asla gömme açıkladı kullanılarak Flush()açıkça denir. Son mod, uzun süre ISessionaçık kaldığı ve bağlantısının kesildiği uzun süre çalışan iş birimleri için kullanışlıdır .

...

Ayrıca bu bölüme bakın :

Bir oturumu sonlandırmak dört farklı aşamadan oluşur:

  • oturumu yıkamak
  • işlemi yap
  • oturumu kapat
  • istisnaları ele al

Oturumu Yıkama

ITransactionAPI kullanıyorsanız, bu adım için endişelenmenize gerek yoktur. İşlem tamamlandığında dolaylı olarak gerçekleştirilecektir. Aksi takdirde ISession.Flush(), tüm değişikliklerin veritabanı ile senkronize edildiğinden emin olmak için aramalısınız .

Veritabanı işleminin gerçekleştirilmesi

NHibernate ITransaction API kullanıyorsanız, şuna benzer:

tx.Commit(); // flush the session and commit the transaction

ADO.NET işlemlerini kendiniz yönetiyorsanız, ADO.NET işlemini el ile yapmanız gerekir Commit().

sess.Flush();
currentTransaction.Commit();

Değişikliklerinizi yerine getirmemeye karar verirseniz:

tx.Rollback();  // rollback the transaction

veya:

currentTransaction.Rollback();

İşlemi geri alırsanız, NHibernate'in dahili durumunun tutarlı olduğundan emin olmak için geçerli oturumu hemen kapatıp atmalısınız.

Oturumun Kapatılması

Bir ISession.Close()oturumun sonunu işaretlemek için yapılan bir çağrı . Close () 'un ana anlamı, ADO.NET bağlantısının oturum tarafından sonlandırılmasıdır.

tx.Commit();
sess.Close();

sess.Flush();
currentTransaction.Commit();
sess.Close();

Kendi bağlantınızı Close()sağladıysanız, buna bir başvuru döndürür, böylece manuel olarak kapatabilir veya havuza geri gönderebilirsiniz. Aksi takdirde Close()havuza geri döndürür.


2
benim için bu satır çok önemliydi: "Close () 'un ana anlamı, ADO.NET bağlantısının oturum tarafından sonlandırılmasıdır." ISession.Close () yöntemini çağırmazsanız, db zaman aşımına uğrayana kadar bağlantılarınız dolar. : o
dave thieben

Biz genellikle: session session.BeginTransaction () çalışma ... session.Transaction.Commit () session.BeginTransaction () çalışma ... session.Transaction.Commit () session.BeginTransaction () çalışma .. session.Transaction.Commit () oturumu atın.
Agile Jedi

Parlak yazma ve +1 ve vb - ancak "Asla kapat kullanmayın" ve daha sonra "İşlemi geri alırsanız, geçerli oturumu hemen kapatıp atmalısınız" dediğiniz için düzenleme yapılması gerektiğini düşünüyorum
SpaceBison

SQL ifadelerinin sırası değiştirilebilir. Ben karşılık gelen tabloda bir kısıtlama var çünkü bir varlık nesnesi üzerinde ve eklemek yerine güncelleme yapmak gerekir demek.
bob_saginowski

14

NHibernate 2.0'dan başlayarak, DB işlemleri için işlemler gereklidir. Bu nedenle, ITransaction.Commit()çağrı gerekli tüm yıkamaları halledecektir. Herhangi bir nedenle NHibernate işlemleri kullanmıyorsanız, oturumun otomatik olarak yıkanması olmayacaktır.


1

ISession zaman zaman ADO.NET bağlantısının durumunu bellekte tutulan nesnelerin durumu ile senkronize etmek için gereken SQL ifadelerini yürütecektir.

Ve her zaman kullan

 using (var transaction = session.BeginTransaction())
 {
     transaction.Commit();
 }

değişiklikler veritabanına kaydetmek için bu değişikliklerden daha sonra tamamlandıktan sonra transaction.Commit ();


0

İşte benim kod oturum olmadan başarısız olur iki örnek:

http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html

bunun sonunda, kimlik eklemeyi ayarladığım, varlığı kaydedip sonra temizlediğim, sonra kimlik eklemeyi ayarladığım bir kod bölümü görebilirsiniz. Bu sifon olmadan kimlik ekini açıp kapatarak varlığı kaydediyor gibiydi.

Flush () kullanımı neler olup bittiğini kontrol etmemi sağladı.

İşte başka bir örnek:

TransactionScope içinde NServiceBus mesajı gönderme

Bunun nedenini tam olarak anlamıyorum, ama Flush () benim hatamın olmasını engelledi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.