Hazırda Bekletme'de session.flush () kullanımı nedir?


110

Bir kaydı güncellediğimizde session.flush()Hibernate ile kullanabiliriz . Ne gerek var flush()?

Yanıtlar:


138

Oturumu temizlemek, Hazırda Bekletme'yi Session, veritabanının bellek içi durumunu veritabanıyla senkronize etmeye zorlar (yani değişiklikleri veritabanına yazmaya). Varsayılan olarak, Hazırda Bekletme değişiklikleri sizin için otomatik olarak temizleyecektir:

  • bazı sorgu yürütmelerinden önce
  • bir işlem yapıldığında

Açıkça yıkamaya izin vermek Session, bazı durumlarda gerekli olabilecek daha ince kontrol sağlar (atanan bir kimlik almak, Oturumun boyutunu kontrol etmek için, ...).


8
Bu cevabın VARSAYILAN Hazırda Bekletme davranışını açıkladığını unutmayın: boşaltma davranışı Yıkama Modu ayarıyla değiştirilebilir. Ayrıntılar docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/… (sürüm 3.5) içindedir .
SteveT

1
Tam olarak ne söylediğinizi söylediğiniz belgeyi buldum ama önceliğin ne olacağı konusunda bir sorum var 1) Kod kullanarak nesneyi kaydettiğim sınıfım var id = session.save(obj);ve işlem hemen sonraki satırda gerçekleştiriliyor ancak obj kaydedilmiyor DB'ye, Neden? 2) session.save(obj);commit ile objeyi kaydettim ve geri dönerken kullandım return obj.getprimaryID();Bu durumda obj DB'ye kaydedildi. Öyleyse neden bu davranış oluyor?
Amogh

74

Yukarıdaki cevaplarda doğru bir şekilde belirtildiği gibi, çağırarak flush(), Veri Tabanında SQL komutlarını yürütmek için hazırda bekletmeye zorlarız. Ancak değişikliklerin henüz "taahhüt edilmediğini" anlayın. Bu nedenle, flush yaptıktan sonra ve commit yapmadan önce, DB'ye doğrudan erişirseniz (örneğin SQL komut isteminden) ve değiştirilen satırları kontrol ederseniz, değişiklikleri GÖRMEZSİNİZ.

Bu, 2 SQL komut oturumu açmakla aynıdır. Ve 1 seansta yapılan değişiklikler, taahhüt edilene kadar başkaları tarafından görülmez.


12
Eh - değişiklikler biraz görünür olabilir. Örneğin, taahhüt edilmemiş bir satır, eklenen ancak taahhüt edilmeyen satırda bir kilit oluşturabilir ve aynı satırın, işlem tamamlanana veya geri alınana kadar başka bir oturum tarafından eklenmesini geciktirebilir. Yani tamamen görünmez değil.
rghome

2
İnternetin her yerinde gezindim ve nihayet anlamamı sağlayan cevap buydu. Teşekkürler.
Siddhartha

Bir for döngüsüne .flush () koymak ne işe yarar ki, eğer commit () sonunda bir flush yaparsa?
Eildosa

@Kaushik Lele Veriler yıkamadan sonra görünmüyorsa, yıkama () noktası nedir? Bunun kullanışlı olduğu daha iyi kullanım durumlarından bazılarını detaylandırabilir misiniz?
java_geek

28

Yalnızca session.flush()ifadelerimizin veritabanında yürütüldüğünü ancak taahhüt edilmediğini biliyorum .

Diyelim ki flush(), oturum nesnesinde yöntemi çağırmıyoruz ve eğer commit yöntemini çağırırsak, veritabanında ifadeleri yürütme ve sonra taahhüt etme işini dahili olarak yapacaktır.

commit=flush+commit (işlevsellik durumunda)

Böylece, Session nesnesinde flush () metodunu çağırdığımızda, commit almadığı, veritabanına isabet ettiği ve sorguyu çalıştırdığı ve geri dönüşü de aldığı sonucuna vardım.

Taahhüt etmek için İşlem nesnesinde commit () kullanıyoruz.


Yıkama ihtiyacının ne olduğu hakkında biraz bilgi verebilir misiniz?
java_geek

14

Oturumu temizlemek, o anda oturumda bulunan verileri veritabanındakilerle eşitlenmiş olarak alır.

Hazırda Beklet web sitesinde daha fazlası:

flush()kullanışlıdır, çünkü Oturum'un JDBC çağrılarını ne zaman yürüteceği konusunda kesinlikle hiçbir garanti yoktur, yalnızca bunların yürütüldüğü sıra - siz kullanmanız dışında flush().


Kullanıcının sıra hakkında endişelenmesi gereken bir senaryo sunabilir misiniz? Hazırda bekletme modu, DB ile ilgili şeyleri kullanıcı için şeffaf hale getirmek içindir. "Kaydetme" yaptığımızda, temizleme otomatik olarak gerçekleşir. Flush yapıp taahhüt etmeyeceğiniz senaryo nedir?
Kaushik Lele

1
@KaushikLele bu soruya başvurabilirsiniz stackoverflow.com/questions/37382872/…
GMsoF

10

flushDoğrulama kısıtlamalarının işlemin gerçekleştirilmesi yerine bilinen bir yerde gerçekleştirilmesini ve tespit edilmesini zorlamak için kullanabilirsiniz . O olabilircommitBazı çerçeve mantığı, bildirim mantığı, kapsayıcı veya bir şablon aracılığıyla örtük olarak çağrılan . Bu durumda, atılan herhangi bir istisnayı yakalamak ve idare etmek zor olabilir (kodda çok yüksek olabilir).

Örneğin save(), adres üzerinde benzersiz bir kısıtlamaya sahip yeni bir EmailAddress nesnesiyseniz, işleme koyana kadar bir hata almazsınız.

çağrı flush() , satırı eklenmeye zorlar ve bir kopya varsa bir İstisna oluşturur.

Ancak, istisnadan sonra oturumu geri almanız gerekecektir.


4

Sadece yukarıda verilen tüm cevapları bir araya getirmek ve daha fazla önem vermek için Flush () yöntemini Session.save () ile ilişkilendirmek istiyorum.

Hazırda bekletme kaydetme (), varlığı veritabanına kaydetmek için kullanılabilir. Bu yöntemi bir işlemin dışında çalıştırabiliriz, bu yüzden bu yöntemi veri kaydetmeyi sevmiyorum. Bunu işlem yapmadan kullanırsak ve varlıklar arasında geçiş yaparsak, o zaman oturumu temizlemediğimiz sürece yalnızca birincil varlık kaydedilir.

flush (): Oturumu temizlemeye zorlar. Veri tabanı ile oturum verilerini senkronize etmek için kullanılır.

Session.flush () 'u çağırdığınızda, ifadeler veritabanında yürütülür ancak taahhüt edilmez. Session.flush () 'u çağırmazsanız ve session.commit ()' i çağırırsanız, dahili olarak commit () metodu ifadeyi çalıştırır ve tamamlar.

Yani commit () = flush + commit. Yani session.flush () sadece veri tabanındaki ifadeleri çalıştırır (ancak teslim etmez) ve ifadeler artık BELLEKTE DEĞİLDİR. Sadece oturumu kızarmaya zorlar.

Birkaç önemli nokta:

İşlem sınırlarının dışına çıkmaktan kaçınmalıyız, aksi takdirde eşlenen varlıklar veri tutarsızlığına neden olacak şekilde kaydedilmeyecektir. Herhangi bir istisna veya uyarı atmadığı için oturumu temizlemeyi unutmak çok normaldir. Varsayılan olarak, Hazırda Bekletme, değişiklikleri sizin için otomatik olarak temizleyecektir: bir işlem gerçekleştirildiğinde bazı sorgu yürütmelerinden önce Oturumu açıkça temizlemeye izin vermek, bazı durumlarda gerekli olabilecek daha hassas kontrol sağlar (atanmış bir kimliği almak, Oturumun boyutunu kontrol etmek için) )


3

flush() Yöntem oturumu temizlemek Hibernate neden olur. setFlushMode()Yöntemi kullanarak Hazırda Bekletme'yi oturum için yıkama modunu kullanacak şekilde yapılandırabilirsiniz . Mevcut oturum için yıkama modunu elde etmek için getFlushMode()yöntemi kullanabilirsiniz . Oturumun kirli olup olmadığını kontrol etmek için kullanabilirsinizisDirty() yöntemi . Varsayılan olarak, Hazırda Bekletme, oturumların yıkanmasını yönetir.

Belgelerde belirtildiği gibi:

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html

Flushing

Temizleme, kalıcılık bağlamının durumunu temeldeki veritabanıyla senkronize etme işlemidir. Ve EntityManagerHazırda BekletmeSession , uygulama geliştiricisinin bir varlığın kalıcı durumunu değiştirebileceği bir dizi yöntemi ortaya çıkarır.

Kalıcılık bağlamı, herhangi bir varlık durumu değişikliğini sıraya koyan işlemsel bir arkaya yazma önbelleği görevi görür. Herhangi bir arkaya yazma önbelleği gibi, değişiklikler ilk olarak bellekte uygulanır ve temizleme süresi sırasında veritabanıyla senkronize edilir. Temizleme işlemi, her varlık durum değişikliğini alır ve bunu bir INSERT, UPDATEveya DELETEifadesine çevirir .

Yıkama stratejisi, çalışmakta olan mevcut Hazırda Bekletme Oturumunun flushMode tarafından verilir . JPA yalnızca iki yıkama stratejisi tanımlasa da ( AUTOve COMMIT), Hibernate çok daha geniş bir yıkama türleri yelpazesine sahiptir:

  • ALWAYS: Her sorgudan önce Oturumu temizler;
  • AUTO: Bu varsayılan moddur ve Oturumu yalnızca gerekirse temizler;
  • COMMIT: Oturum, mevcut İşlem tamamlanana kadar boşaltmayı ertelemeye çalışır, ancak yine de vaktinden önce boşaltabilir;
  • MANUAL: Oturum temizleme yetkisi Session.flush(), kalıcılık bağlam değişikliklerini uygulamak için açıkça çağırması gereken uygulamaya devredilir .

Varsayılan olarak, Hazırda Bekletme AUTOaşağıdaki durumlarda yıkamayı tetikleyen yıkama modunu kullanır :

  • bir İşlem gerçekleştirmeden önce;
  • sıraya alınmış varlık eylemleriyle örtüşen bir JPQL / HQL sorgusu yürütmeden önce;
  • kayıtlı senkronizasyonu olmayan herhangi bir yerel SQL sorgusunu yürütmeden önce.

1

Çağrı EntityManager#flushvar yan etkileri . Oluşturulan kimlik değerlerine (sıra değerleri) sahip varlık türleri için uygun şekilde kullanılır: böyle bir kimlik yalnızca temeldeki kalıcılık katmanı ile senkronizasyon üzerine kullanılabilir. Bu kimlik, geçerli işlem sona ermeden önce gerekliyse (örneğin, günlük kaydı amacıyla), oturumun temizlenmesi gerekir.


0

Bu yöntemle yıkama sürecini uyandırırsınız. Bu işlem, durum değişikliklerini algılayarak ve ilgili SQL ifadelerini çalıştırarak veritabanınızın durumunu oturum durumunuzla senkronize eder.

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.