druid连接池异常

在从excel导入10W条数据到mysql中时,运行一段时间就会抛这个异常,连接池问题 

Java代码   收藏代码
  1. org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.TransactionException: JDBC begin failed:  
  2. Caused by: java.sql.SQLException: connection holder is null  
  3.     at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1085)  
  4.     at com.alibaba.druid.pool.DruidPooledConnection.getMetaData(DruidPooledConnection.java:825)  
  5.     at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:285)  

找了下解决方案 
1. 

给jdbc url 增加 autoReconnect=true 一定能解决你的问题,可以定期观察一下 show processlist 
改进方法如下: 
<property name="url" value="jdbc:mysql://localhost/数据库实例名称?&useUnicode=true&characterEncoding=utf-8&autoReconnect=true"/> 

2. 

寻找支持重连的连接池。 
           注意:c3p0连接池支持重连;重连参数是: 
               idleConnectionTestPeriod   设置空闲连接测试周期 
               preferredTestQuery : 设置一查询语句,用于重连测试 
              testConnectionOnCheckin设置为true 
              testConnectionOnCheckout设置为true 

在sessionFactory里配置: 

<property name="hibernateProperties"> 
   <props> 

        <prop key="hibernate.autoReconnect">true</prop> 

  </props> 
</property> 
这两种不同的配置都是使连接池自动重连 

后面发现问题还是存在 

通过研究源码我可以确定"Druid提供的getConnection()或者getConnection(long maxWaitMillis)方法不能保证在同一个线程中获取的始终是一个连接,直到显示的将连接关闭吗?"。必须在程序在缓存从Druid中取出的连接才能保证现一个事务在使用的是同一个连接。 

而抛出“connection holder is null”异常的原因可能在于: 

关闭长时间不使用的连接超时时间,单位秒 
removeAbandonedTimeout 

假设这个参数的值 为30分钟,当一个连接在获取后30分钟还没释放,也就是Connection的DruidPooledPreparedStatement对象执行完了executXXX()方法但还未执行close、commit、rollback方法,对应于Connection的running参数的值为false,这时Durid的DestroyConnectionThread线程会自动将该连接回收。当程序要commit()连接时会执行checkState()方法,这个方法会执行以下代码: 

Java代码   收藏代码
  1. if (holder == null) {    
  2.  if (disableError != null) {    
  3.    throw new SQLException("connection holder is null", disableError);    
  4.     } else {    
  5.    throw new SQLException("connection holder is null");    
  6.     }    
  7. }   


这段代码就是我们看到的“connection holder is null”异常的来源,因此,我们需要做的就是根据Druid提供的监控信息(主要看“连接持有时间分布”的值)修改这个参数的值,它的值一定要比最长的连接持有时间还要大。 

最后我把链接自动清除配置关闭解决了问题 
removeAbandoned=false 
如果把这个时间调整大一点应该也是可以的 

removeAbandonedTimeout=1800 


转载于:http://qiaoyihang.iteye.com/blog/2321858

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值