Kontroluj sesję hibernate(kiedy zamknąć ją ręcznie)
Jestem nowy w hibernate,po przeczytaniu API hibernate i samouczka wydaje się,że sesja powinna zostać zamknięta, gdy nie jest używana.
Tak:
Session sess=getSession();
Transcration tx=sess.beginTranscration();
//do something using teh session
sess.save(obj);
tx.commit();
sess.close;
Nie mam wątpliwości, gdy używam go w samodzielnej aplikacji. Jednak nie jestem pewien, kiedy używasz w aplikacji internetowej.
Na przykład, mam servlet: TestServlet
aby odbierać parametry od klienta, następnie wzywam menedżera, aby odpytywał coś zgodnie z parametrami, tak jak to:
class TestServlet{
doGet(HttpServletRequset,httpServletResponse){
String para1=request.getParam...();
String para2=.....
new Manager().query(para1,para2);
}
}
class Manager{
public String query(String pa1,String pa2){
Session=....// get the session
//do query using para1 and 1
session.close() //Here, I wonder if I should close it.
}
}
Czy powinienem zamknąć sesja w metodzie zapytań?
Ponieważ ktoś mi powiedział, że sesja w hibernate jest jak połączenie w jdbc. Więc otwieranie i zamykanie go tak często jest właściwym sposobem?
BTW, czy tx.commit() jest wymagany za każdym razem?
Również jaki jest problem z używaniem sesji w servlecie, ponieważ widziałem, że sesja nie jest bezpieczna dla wątku w api.
3 answers
Jestem nowy w hibernate,po przeczytaniu API hibernate i samouczka wydaje się, że sesja powinna być cloesd, gdy nie jest używana.
Powinno być zamknięte, gdy skończysz z (ale może to być zrobione automatycznie dla Ciebie, jak zobaczymy).
Nie mam wątpliwości, gdy używam go w samodzielnej aplikacji. Jednak nie jestem pewien, kiedy używasz w aplikacji internetowej.
Jak wyjaśniono w sekcji 11.1.1. Jednostka pracy dokumentacji, najczęściej spotykanym wzorcem w aplikacji klienckiej/serwerowej dla wielu użytkowników jest session-per-request.
Na przykład, mam servlet: TestServlet, aby odbierać parametry od klienta,następnie wzywam menedżera, aby odpytywał coś zgodnie z parametrami: tak po prostu (...) Czy powinienem zamknąć sesję w metodzie query?
Wszystko zależy od tego, jak uzyskasz sesję.
- jeśli użyjesz
sessionFactory.getCurrentSession()
, uzyskasz "bieżącą sesję", która jest związany z cyklem życia transakcji i będzie automatycznie spłukiwany i zamykany po zakończeniu transakcji (commit lub rollback). - jeśli zdecydujesz się użyć
sessionFactory.openSession()
, będziesz musiał samodzielnie zarządzać sesją oraz spłukać i zamknąć ją "ręcznie".
Aby zaimplementować wzorzec session-per-request, preferuj pierwsze podejście (znacznie łatwiejsze i mniej gadatliwe). Skorzystaj z drugiego podejścia, aby wdrożyć długie rozmowy.
Strona wiki sesje i transakcje jest dobrym uzupełnieniem dokumentacji na ten temat.
BTW, czy tx.commit() jest wymagany za każdym razem?
Możesz przeczytać Nietransakcyjny dostęp do danych i tryb Auto-commit , aby wyjaśnić kilka rzeczy, ale mówiąc prościej, Twój kod hibernacji musi zostać wykonany w ramach transakcji i sugerowałbym użycie jawnych granic transakcji(tj. jawnych beginTransaction
i commit
).
Również to, co jest problem z używaniem sesji w servlecie, ponieważ widziałem, że sesja nie jest Bezpieczna w api.
Tylko nie rób z niej zmiennej instancji Servletu i nie będziesz miał żadnego problemu.
Referencje
- Hibernate Core 3.3 Reference Guide
- Hibernate wiki
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-15 15:08:08
Jeśli otrzymujesz sesję Przez sessionFactory.openSession()
, musisz zamknąć ją zewnętrznie . Otwarta sesja na niezamierzony okres może spowodować wyciek danych. Plus może dać zaproszenie do zagrożenia bezpieczeństwa aplikacji internetowej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 12:17:48
Możemy wykorzystać ThreadLocal
.
public class MyUtil {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
private static final ThreadLocal<Session> threadLocal;
static {
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
threadLocal = new ThreadLocal<Session>();
} catch(Throwable t){
t.printStackTrace();
throw new ExceptionInInitializerError(t);
}
}
public static Session getSession() {
Session session = threadLocal.get();
if(session == null){
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
public static void closeSession() {
Session session = threadLocal.get();
if(session != null){
session.close();
threadLocal.set(null);
}
}
public static void closeSessionFactory() {
sessionFactory.close();
StandardServiceRegistryBuilder.destroy(serviceRegistry);
}
}
Tutaj {[2] } jest inicjalizowane tylko raz za pomocą bloku statycznego. Dlatego, gdy klasa main
wywoła getSession()
, obecność obiektu Session jest najpierw sprawdzana w obiekcie threadLocal
.
Dlatego ten program zapewnia bezpieczeństwo wątków.
Po każdej operacji closeSession()
zamknie sesję i ustawi obiekt threadLocal
Na null.
Na koniec zadzwoń do closeSessionFactory()
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-04 16:22:45