Hazırda bekletme openSession () vs getCurrentSession ()


130

JSP web uygulamasında Hibernate'i kullanmakla ilgili bazı sorularım var.

  1. Değer ne olmalıdır hibernate.current_session_context_class?

  2. O halde aşağıdaki ifadelerden hangisi kullanılmalıdır? Ve neden?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. Son olarak, "web uygulaması başına bir oturum" veya "istek başına bir oturum" hangisi daha iyidir?

Yanıtlar:


145

Bu forum gönderisinde açıklandığı gibi , 1 ve 2 birbiriyle ilişkilidir. İş hibernate.current_session_context_classparçacığını ayarlarsanız ve daha sonra oturumu açan sunucu uygulaması filtresi gibi bir şey uygularsanız - o zaman o oturuma SessionFactory.getCurrentSession().

SessionFactory.openSession()her zaman işlemleri tamamladığınızda kapatmanız gereken yeni bir oturum açar. SessionFactory.getCurrentSession()bir bağlama bağlı bir oturum döndürür - bunu kapatmanıza gerek yoktur.

İşlemleri yönetmek için Spring veya EJB kullanıyorsanız, bunları işlemlerle birlikte oturumları açacak / kapatacak şekilde yapılandırabilirsiniz.

Asla kullanmamalısınız one session per web app- oturum, iş parçacığı güvenli bir nesne değildir - birden çok iş parçacığı tarafından paylaşılamaz. Her zaman "istek başına bir oturum" veya "işlem başına bir oturum" kullanmalısınız


Çok teşekkür ederim @gkamal. Görünümde Açık Oturum'daki koda bakıyorum . (Bağlantınız bu belgelere işaret ediyor.) Yazar filtre kullanımını öneriyor. Filtre kodunda openSession()veya aramıyor close(). Sadece arıyor getCurrentSession(). Onun setleri tahmin current_session_contextetmek thread. Şimdi anladığımı düşünüyorum getCurrentSession(). Ancak ne zaman kullanmam gerektiğini bilmiyorum openSession().
wannik

4
Oturumun herhangi bir bağlama bağlı olmasını istemiyorsanız OpenSession'ı kullanacaksınız. Bağlama bağlı olandan farklı bir oturuma ihtiyaç duyduğunuz bazı durumlar vardır (Hazırda Durdurucuların orijinal oturumu kullanamayacağınız bir sınırlaması vardır) - bu durumlarda currentSession yerine OpenSession kullanırsınız. OpenSession, açıkça kapatmanız gereken yeni bir oturum oluşturur. Örneğin, bir DAO yönteminde OpenSession'ı çağırırsınız - oturumu kullanın ve kapatın.
gkamal

getCurrentSession () kullanıyorum; çünkü onu dinleyicide başlattım, filtre değil bu sizin görüşünüzden ok; mvc2 jsp servlet kullanıyorum
Shareef'ten

@gkamal - ile ilgili bir sorum var Sessions. Lütfen bana yardım edebilir misiniz - stackoverflow.com/questions/23351083/… . Teşekkür ederim ve Chenqui.
Erran Morad

IMO, her iş parçacığının kendi Oturumunu ve yalnızca bir Oturumu tutmasına izin vermek iyi bir uygulamadır, değil mi?
coderz

31

SessionFactory.openSession () hakkında konuşursak

  • Her zaman yeni bir Session nesnesi oluşturur.
  • Oturum nesnelerini açıkça yıkamanız ve kapatmanız gerekir.
  • Tek iş parçacıklı ortamda getCurrentSession () 'dan daha yavaştır.
  • Bu yöntemi çağırmak için herhangi bir özelliği yapılandırmanıza gerek yoktur.

Ve SessionFactory.getCurrentSession () hakkında konuşursak

  • Mevcut değilse yeni bir Oturum oluşturur, yoksa aynı oturumu mevcut hazırda bekletme bağlamında kullanır.
  • Oturum nesnelerini temizlemenize ve kapatmanıza gerek yoktur, bunlar otomatik olarak dahili olarak Hazırda Bekletme tarafından halledilecektir.
  • Tek iş parçacıklı ortamda openSession () 'dan daha hızlıdır.
  • Ek mülk yapılandırmanız gerekir. getCurrentSession () yöntemini çağırmak için "hibernate.current_session_context_class", aksi takdirde bir istisna atar.

Yukarıdaki cevap, web uygulaması başına tek bir oturum kullanmamayı söylüyor. Bu yüzden eğer kullansaydım getCurrentSession, aynı seansı tekrar kullanırdım , değil mi?
parsecer

9

openSession: Aradığınızda SessionFactory.openSessionher zaman yeni birSession nesne ve size verir.

Bu oturum nesnelerini açıkça temizlemeniz ve kapatmanız gerekir.

Oturum nesneleri olmadığından iş parçacığı güvenli , çok iş parçacıklı ortamda istek başına bir oturum nesnesi ve web uygulamalarında da istek başına bir oturum oluşturmanız gerekir.

getCurrentSession: Aradığın zaman SessionFactory.getCurrentSession , size hazırda bekletme bağlamında olan ve dahili olarak hazırda bekletme ile yönetilen oturum nesnesi sağlayacaktır. İşlem kapsamına bağlıdır.

Aradığınızda SessionFactory.getCurrentSessionyeni birSession yoksa , aksi takdirde mevcut hazırda bekletme bağlamında olan aynı oturumu kullanın. İşlem bittiğinde oturumu otomatik olarak temizler ve kapatır, böylece bunu harici olarak yapmanız gerekmez.

Tek iş parçacıklı ortamda hazırda bekletme kullanıyorsanız getCurrentSession, her seferinde yeni bir oturum oluşturmaya kıyasla performans açısından daha hızlı olduğu için kullanabilirsiniz .

Yöntemi kullanmak için hibernate.cfg.xml dosyasına aşağıdaki özelliği eklemeniz gerekir getCurrentSession:

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>

Sunucu uygulaması her istek için yeni bir iş parçacığı açmaz mı? Yani bir Java web uygulamasıysa, zaten tek iş parçacıklı bir ortam değil mi?
parsecer

0
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Parameter            |                                openSession                                 |                                          getCurrentSession                                          |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session  creation    | Always open new session                                                    | It opens a new Session if not exists , else use same session which is in current hibernate context. |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session close        | Need to close the session object once all the database operations are done | No need to close the session. Once the session factory is closed, this session object is closed.    |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Flush and close      | Need to explicity flush and close session objects                          | No need to flush and close sessions , since it is automatically taken by hibernate internally.      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Performance          | In single threaded environment , it is slower than getCurrentSession       | In single threaded environment , it is faster than openSession                                      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Configuration        | No need to configure any property to call this method                      | Need to configure additional property:                                                              |
|                      |                                                                            |  <property name=""hibernate.current_session_context_class"">thread</property>                       |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+

-6

SessionFactory: "DataBase başına uygulama başına bir SessionFactory" (örneğin, uygulamamızda 3 DataBase kullanırsanız, her DB için sessionFactory nesnesi oluşturmanız gerekir, toplamda 3 sessionFactorys oluşturmanız gerekir. Veya yalnızca bir DataBase One oturum fabrikanız varsa yeterlidir ).

Oturum: "Bir istek-yanıt döngüsü için bir oturum". talep geldiğinde oturum açabilir ve talep işlemi tamamlandıktan sonra oturumu kapatabilirsiniz. Not: -Web uygulaması için tek oturum kullanmayın.

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.