Bootstrap

关于Druid连接池控制事务出现connection holder is null异常

上周练习JDBC时,使用Druid和ThreadLocal来控制事务的开启、提交、回滚,后期使用时出现了connection holder is null的异常,一开始以为是因为事务长时间未提交,自动关闭连接,后来改变了配置依然不行。

该异常的出现是属于获取连接超时,从而找不到持有者,本来每次事务提交或回滚后都应该关闭连接,ThreadLocal中移除connection对象,后来发现我的ThreadLocal.remove()方法放的位置不准确。

一开始放到resultSet关闭的if里,导致没有使用resultSet时并没有移除ThreadLocal的connection,导致ThreadLocal里关闭的connection对象没有及时remove,下一次使用时没办法获取正常运行的connection。

错误代码

public static void close(Connection connection, Statement statement, ResultSet resultSet){
  if(connection != null){
    try {
      connection.close();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  if(statement != null){
    try {
      statement.close();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  if(resultSet != null){
    try {
      resultSet.close();
        THREAD_LOCAL.remove();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
}

改正后

public static void close(Connection connection, Statement statement, ResultSet resultSet){
  if(connection != null){
    try {
      connection.close();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  if(statement != null){
    try {
      statement.close();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  if(resultSet != null){
    try {
      resultSet.close();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  THREAD_LOCAL.remove();
}
;