重大改版
 鱼翔空 2015-01-23 hibernate,技术总结|   0 1037 
文章评分 90 次,平均分 5.0

项目跑了一段时间后出现了获取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

 

除特别注明外,本站所有文章均为我要编程原创,转载请注明出处来自http://5ycode.com/article/88.html

关于
该用户很懒!
切换注册

登录

忘记密码 ?

切换登录

注册

扫一扫二维码分享