標籤:
服務端新開多線程使用HibernateSession 杜絕No session
新起的線程需要綁定Hibernate session,才能在新線程中使用事務和消極式載入等功能,否則會曝出no session異常;
解決辦法:
[java] view plaincopy
- new Runnable() {
- @Override
- public void run() {
- // ----------綁定session到當前線程------------
- SessionFactory sessionFactory = (SessionFactory)applicationContext.getBean("sessionFactory");
- boolean participate = ConcurrentUtil.bindHibernateSessionToThread(sessionFactory);
- // ---------你的業務---------------
- <pre name="code" class="java">// ----------關閉session------------
- ConcurrentUtil.closeHibernateSessionFromThread(participate, sessionFactory);
- }
-
- }
bindHibernateSessionToThread方法:
[java] view plaincopy
- public static boolean bindHibernateSessionToThread(SessionFactory sessionFactory) {
- if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
- // Do not modify the Session: just set the participate flag.
- return true;
- } else {
- Session session = sessionFactory.openSession();
- session.setFlushMode(FlushMode.MANUAL);
- SessionHolder sessionHolder = new SessionHolder(session);
- TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
- }
- return false;
- }
closeHibernateSessionFromThread方法
[java] view plaincopy
- public static void closeHibernateSessionFromThread(boolean participate, Object sessionFactory) {
-
- if (!participate) {
- SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.unbindResource(sessionFactory);
- SessionFactoryUtils.closeSession(sessionHolder.getSession());
- }
- }
事務邊界則由aop或者Transactional標記來控制,範例程式碼只是保證具備事務性的方法在需要的時候能從當前線程中獲得session對象。
上述代碼大部分截取自Spring的OpenSessionInViewFilter。
java多線程使用HibernateSession 時報 No session 的解決辦法(轉)