项目跑了一段时间后出现了获取Session异常
org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.TransactionException: JDBC begin failed:
.....
Caused by: org.hibernate.TransactionException: JDBC begin failed:
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:92)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473)
Caused by: java.sql.SQLException: Io 异常: Connection reset by peer: socket write error
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
出现该问题的可能性:
1)连接池的链接过少,增加连接池的最大链接数量
2)链接释放不及时,解决办法
<bean id="sessionFactory" class="AnnotationSessionFactoryBean" > <property name="hibernateProperties"> <props> <prop key="hibernate.connection.release_mode">after_statement</prop> </props> </property> </bean>
在替换druid链接后出现该问题,以前没有替换连接池是事务都是正常的,替换druid连接池后通过页面新增,修改异常(新增,修改在基类中),删除可以删除(删除是自定义的方法)
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
后台跑的job,使用新增,修改都可以跑,都能正常提交。
分析原因,通过url访问的方法,数据库提交模式被改变了,具体被谁改变了,暂时没找到
解决方法:将FlushMode,更改为auto,有两种方式,
一是:在web.xml中使用 OpenSessionInViewFilter 过滤器
<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>flushMode</param-name> <param-value>AUTO</param-value> </init-param> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
二是:在spring配置文件中使用openSessionViewInterceptor拦截器
<bean name="openSessionViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> <property name="sessionFactory" ref="sessionFactory" /> <!-- FLUSH_NEVER = 0 翻看 OpenSessionInViewInterceptor源码找到的 FLUSH_AUTO = 1 FLUSH_EAGER = 2 FLUSH_COMMIT = 3 FLUSH_ALWAYS = 4 --> <property name="flushMode" value="1"/> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <!-- 是否为全路径 --> <!-- <property name="alwaysUseFullPath" value="true" /> --> <property name="interceptors"> <list> <ref bean="openSessionViewInterceptor" /> </list> </property> </bean>
查看OpenSessionInViewFilter的源代码,发现这里默认设置了MANUAL,可是我的web.xml中根本就没有配置OpenSessionInViewFilter,真是一个奇怪的问题,有空得好好的找下
public class OpenSessionInViewFilter extends OncePerRequestFilter { public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory"; private String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME; private boolean singleSession = true; private FlushMode flushMode = FlushMode.MANUAL; .... }
原理性的东西可以参考http://justsee.iteye.com/blog/1174999
文章评论