spring 控制hibernate的session何时关闭.
?http://blog.csdn.net/dengyin2000/article/details/448341
?
在用spring管理hierbernate的事務我們一般都用TransactionProxyFactoryBean去配置我們的Service方法.
如.
?<bean id="baseTxProxy" lazy-init="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
??????? <property name="transactionManager"><ref bean="transactionManager"/></property>
??????? <property name="transactionAttributes">
??????????? <props>
????<prop key="*">PROPAGATION_REQUIRED</prop>
????<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>??
????<prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>?????????
????<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>?????
??????????? </props>
??????? </property>
??? </bean>
?
<!-- <bean id="userManager" parent="baseTxProxy">
??????? <property name="target">
??????????? <bean class="com.javaeye.user.impl.hibernate.UserManagerImpl" autowire="byName">
??????????????? <property name="cacheQueries"><value>true</value></property>
??????????? </bean>
??????? </property>
??? </bean>
-->??????
?
?<bean id="userService" parent="baseTxProxy">
??<property name="target">
???<bean class="com.dengyin.report.service.impl.UserServiceImpl" autowire="byName"/>
??</property>
?</bean>
?
?<bean id="dailyReportService" parent="baseTxProxy">
??<property name="target">
???<bean class="com.dengyin.report.service.impl.DailyReportServiceImpl" autowire="byName"/>
??</property>
?</bean>
我們可以想得到TransactionProxyFactoryBean是使用aop在Service方法之前open 一個session, begin Trans.在Service結束之后Commit Trans, close session.
note:如果一個service中調用另外一個service,如果另外一個service的事務傳播類型是required的話,那么兩個service中使用的是同一個session
但是我們使用spring的OpenSessionInViewFilter的時候就不能在Service方法后close session了. 應該是在Render page之后再關閉session的.所以我跟蹤了spring的代碼. 最后發現了spring是怎樣做的(跟了好久,主要是上班偷偷摸摸搞的).
???HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
???if (txObject.getSessionHolder() == null) {
????Interceptor entityInterceptor = getEntityInterceptor();
????Session newSession = (entityInterceptor != null ?
??????getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());
????if (logger.isDebugEnabled()) {
?????logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
????}
????txObject.setSessionHolder(new SessionHolder(newSession), true);
???}
???txObject.getSessionHolder().setSynchronizedWithTransaction(true);
???session = txObject.getSessionHolder().getSession();
這段代碼是在進行Service之前的. 如果當前thread沒有session的話就執行txObject.setSessionHolder(new SessionHolder(newSession), true);注意這里set了一個true值. 我們來看看txObject是一個什么東西.
?private static class HibernateTransactionObject extends JdbcTransactionObjectSupport {
??private SessionHolder sessionHolder;
??private boolean newSessionHolder;
??public void setSessionHolder(SessionHolder sessionHolder, boolean newSessionHolder) {
???this.sessionHolder = sessionHolder;
???this.newSessionHolder = newSessionHolder;
??}
??public SessionHolder getSessionHolder() {
???return sessionHolder;
??}
??public boolean isNewSessionHolder() {
???return newSessionHolder;
??}
??public boolean hasTransaction() {
???return (this.sessionHolder != null && this.sessionHolder.getTransaction() != null);
??}
??public void setRollbackOnly() {
???getSessionHolder().setRollbackOnly();
???if (getConnectionHolder() != null) {
????getConnectionHolder().setRollbackOnly();
???}
??}
??public boolean isRollbackOnly() {
???return getSessionHolder().isRollbackOnly() ||
?????(getConnectionHolder() != null && getConnectionHolder().isRollbackOnly());
??}
?}
我們看看Service方法之后spring怎樣close session的.
??Session session = txObject.getSessionHolder().getSession();
??if (txObject.isNewSessionHolder()) {
???if (logger.isDebugEnabled()) {
????logger.debug("Closing Hibernate Session [" + session + "] after transaction");
???}
???SessionFactoryUtils.releaseSession(session, getSessionFactory());
??}
??else {
???if (logger.isDebugEnabled()) {
????logger.debug("Not closing pre-bound Hibernate Session [" + session + "] after transaction");
???}
???if (txObject.getSessionHolder().getPreviousFlushMode() != null) {
????session.setFlushMode(txObject.getSessionHolder().getPreviousFlushMode());
???}
??}
??txObject.getSessionHolder().clear();
當txObject.isNewSessionHolder()的時候才會close? session.
總結:
所以當Service方法之間沒有存在的session時spring會開一session,然后結束的時候close session.
當Service方法之間有存在的session的話,Service方法結束時并沒有關閉? session.
總結
以上是生活随笔為你收集整理的spring 控制hibernate的session何时关闭.的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用SQLQuery
- 下一篇: hibernate 联合主键 merge