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

  • 相关阅读:
    因为这几个TypeScript代码的坏习惯,同事被罚了500块
    如何设计好分布式数据库,这个策略很重要
    线程、多线程和线程池,看完这些你就能全部搞懂了
    章方:征服耶鲁教授的算法大神程序媛
    从零开始学python | 使用Python映射,过滤和缩减函数:所有您需要知道的
    c# 优化代码的一些规则——用委托表示回调[五]
    mysql 重新整理——索引优化explain字段介绍一 [九]
    mysql 重新整理——索引优化explain简单介绍 [八]
    mysql 重新整理——索引简介[七]
    mysql 重新整理——七种连接join连接[六]
  • 原文地址:https://www.cnblogs.com/qiaoyihang/p/6166159.html
Copyright © 2011-2022 走看看