Управление сеансом спящего режима (когда его закрыть вручную)

Я новичок в спящем режиме, после чтения hibernate api и учебника, кажется, что сеанс должен быть закрыт, когда он не используется.

Как это:

Session sess=getSession(); Transcration tx=sess.beginTranscration(); //do something using teh session sess.save(obj); tx.commit(); sess.close; 

Я не сомневаюсь при использовании его в отдельном приложении. Однако я не уверен при использовании в веб-приложении.

Например, у меня есть сервлет: TestServlet для получения параметров от клиента, затем я вызываю диспетчера для запроса чего-либо в соответствии с параметрами, как это:

 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. } } 

Должен ли я закрывать сеанс в методе запроса?

Поскольку кто-то сказал мне, что сеанс в спящем режиме похож на соединение в jdbc. Так что открытие и закрытие так часто – правильный путь?

BTW, требуется ли tx.commit () каждый раз?

Также проблема с streamом в использовании сеанса в сервлете, поскольку я видел, что сеанс не является streamобезопасным в api.

    Я новичок в спящем режиме, после чтения hibernate api и учебника, кажется, что сессия должна быть закрыта, если не используется.

    Он должен быть закрыт, когда вы закончите (но это может быть сделано автоматически для вас, как мы увидим).

    При использовании в автономном приложении я не сомневаюсь. Однако я не уверен при использовании в веб-приложении.

    Ну, как объясняется в разделе 11.1.1. Единицей работы документации, наиболее распространенной схемой в многопользовательском клиент-серверном приложении является сеанс за запрос .

    Например, у меня есть сервлет: TestServlet для получения параметров от клиента, затем я вызываю диспетчера для запроса чего-либо в соответствии с параметрами: точно так же (…) Должен ли я закрывать сеанс в методе запроса?

    Все зависит от того, как вы получаете сеанс.

    • если вы используете sessionFactory.getCurrentSession() , вы получите «текущий сеанс», привязанный к жизненному sessionFactory.getCurrentSession() транзакции, и при завершении транзакции будет автоматически очищаться и закрываться (фиксация или откат).
    • если вы решите использовать sessionFactory.openSession() , вам придется самостоятельно управлять сеансом и sessionFactory.openSession() его вручную.

    Чтобы реализовать шаблон сеанса за запрос , предпочитайте первый подход (гораздо проще и менее подробным). Используйте второй подход для реализации длинных разговоров .

    Вики-страница Сессии и транзакции являются хорошим дополнением к документации по этой теме.

    BTW, требуется ли tx.commit () каждый раз?

    Возможно, вам захочется прочитать доступ к данным без транзакций и режим автоматической фиксации, чтобы прояснить некоторые вещи, но, проще говоря, ваш код Hibernate должен выполняться в транзакции, и я предлагаю использовать явные границы транзакций (т. Е. явное beginTransaction и commit ).

    Также проблема с streamом в использовании сеанса в сервлете, поскольку я видел, что сеанс не является streamобезопасным в api.

    Просто не делайте его переменной экземпляра сервлета, и у вас не будет никаких проблем.

    Рекомендации

    • Справочное руководство Hibernate Core 3.3
      • Глава 11. Транзакции и параллелизм
    • Hibernate wiki
      • Сессии и транзакции
      • Доступ к транзакционным данным и режим автоматической фиксации

    Если вы получаете сеанс через sessionFactory.openSession() вам нужно закрыть его извне . Открытая сессия в течение непредвиденного периода может привести к утечке данных. Кроме того, он может дать приглашение угрозе безопасности веб-приложений.

    Мы можем использовать ThreadLocal .

     public class MyUtil { private static SessionFactory sessionFactory; private static ServiceRegistry serviceRegistry; private static final ThreadLocal threadLocal; static { try { Configuration configuration = new Configuration(); configuration.configure(); serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); threadLocal = new ThreadLocal(); } 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); } } 

    Здесь SessionFactory инициализируется только один раз с использованием статического блока. Следовательно, всякий раз, когда main class вызывает вызов getSession() , присутствие объекта Session сначала проверяется в объекте threadLocal . Поэтому эта программа обеспечивает безопасность streamов. После каждой операции closeSession() закроет сеанс и установит для объекта threadLocal значение null. Наконец вызовите closeSessionFactory() .

    Давайте будем гением компьютера.