zoukankan      html  css  js  c++  java
  • druid连接池异常


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

    org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is org.hibernate.TransactionException: JDBC begin failed:
    Caused by: java.sql.SQLException: connection holder is null
    	at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1085)
    	at com.alibaba.druid.pool.DruidPooledConnection.getMetaData(DruidPooledConnection.java:825)
    	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()方法,这个方法会执行以下代码:

    if (holder == null) {  
     if (disableError != null) {  
       throw new SQLException("connection holder is null", disableError);  
        } else {  
       throw new SQLException("connection holder is null");  
        }  
    } 
    



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

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

  • 相关阅读:
    【Maven】安装配置、目录结构、配置文件、常见命令
    【Maven】基础概念、仓库、构建与部属
    【float】与【position】汇总
    【CSS】定义元素的对齐方式
    【CSS】元素样式
    【CSS】绝对定位和相对定位
    网页常见布局
    php--常用的时间处理函数
    16位cpu下主引导扇区及用户程序的编写
    浅谈pageobject模式
  • 原文地址:https://www.cnblogs.com/qiaoyihang/p/6166159.html
Copyright © 2011-2022 走看看