2017-01-09 31 views
2

我的Spring應用程序始終使用@org.springframework.transaction.annotation.Transactional來打開事務。爲了減少與交易有關的不必要的開銷,我已經開始刪除不需要交易的應用領域中的一些註釋。什麼決定在@Transactional之外是否有休眠會話

這樣做,我注意到@Controller類已刪除@Transactional註釋(在類級別或方法級別)仍然能夠使用SessionFactory#getCurrentSession()。然而,當我從@Service(具體地說,的org.springframework.security.core.userdetails.UserDetailsService實現)取出@Transactional註釋,並試圖打電話SessionFactory#getCurrentSession(),我收到了以下:

Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread 
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134) 
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) 
    at com.xxx.datasource.AbstractDAO.getSession(AbstractDAO.java:35) 
    at com.xxx.datasource.UserDAO.getLoginUser(UserDAO.java:209) 
    at com.xxx.datasource.UserDAO.getLoginUser(UserDAO.java:199) 
    at com.xxx.spring.userdetails.service.UserDetailsServiceImpl.loadUserByUsername(UserDetailsServiceImpl.java:24) 
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:102) 
    ... 49 more 

這究竟是爲什麼/什麼確定SessionFactory#getCurrentSession()將返回一個會話或拋出異常?

(春季4.1.9和4.3.11休眠)

+0

Spring通過使用過濾器保持打開供網站使用的hibernate會話。請參閱[http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.html]。但是這隻適用於視圖,而在服務器端,您需要擁有自己的事務註釋標記來根據需要管理事務。 –

回答

1

方法調用SesssionFactory.getCurrentSession()的方法/類不@Transactional annotatated會導致異常作爲TransactionSynchronizationManager.isSynchronizationActive()將返回false。它返回false,因爲@Transaction方面尚未執行,因此事務同步對於當前線程保持不活動狀態。如果它被執行,它將激活當前線程的事務同步。 方法看:TransactionSynchronizationManager.initSynchronizationTransactionSynchronizationManager.isSynchronizationActive

正如你提到你的@Controller類工作正常,這可能是因爲他們要麼不執行任何操作DAO或提前於控制器層正在交易的照顧。

+0

謝謝。我應該事先看過這個,但現在我可以確認'OpenSessionInViewInterceptor'是有罪的。我的印象是這種模式只有在請求到達視圖層時纔打開會話*;但事實上,由於它是一個彈簧攔截器,在控制器方法被擊中之前,它在攔截器的'preHandle'階段打開它。 – jlb