此类从数据库池获取连接有什么问题

时间:2015-10-21 16:13:48

标签: java mysql jdbc connection-pooling hikaricp

我写了一个类来从数据库池( HikariCP )获取连接。我搜索了错误,这意味着连接已关闭。但是,我无法弄清楚问题所在。我确信我在代码中做错了,可能没有正确关闭连接或者其他因为一段时间后我开始出现如下错误:

11:27:58.843 [http-apr-8080-exec-10] WARN  c.z.h.u.ConcurrentBag -
**Attempt to remove an object from the bag that does not exist: com.mysql.jdbc.JDBC4Connection@5f3145e5, created Oct 21, 11:27:12.734, last release 0ms ago, NOT_IN_USE 11:27:58.861 [http-apr-8080-exec-10] ERROR c.p.d.DAOConnectionFactory - Error while closing connection.** java.sql.SQLException: Connection is closed   at com.zaxxer.hikari.proxy.ClosedConnection$1.invoke(ClosedConnection.java:51) ~[HikariCP-2.4.1.jar:na]     at com.sun.proxy.$Proxy4.clearWarnings(Unknown Source) ~[na:na]     at com.zaxxer.hikari.proxy.ConnectionProxy.close(ConnectionProxy.java:197) ~[HikariCP-2.4.1.jar:na]     at com.presence.dao.DAOConnectionFactory.closeConnection(DAOConnectionFactory.java:73)
**~[DAOConnectionFactory.class:na]   11:28:01.133 [http-apr-8080-exec-9] WARN  c.z.h.p.ConnectionProxy - HikariPool-0 - Connection com.mysql.jdbc.JDBC4Connection@46fb3f92, created Oct 21, 11:27:12.781, last release 28ms ago, IN_USE marked as broken because of SQLSTATE(08003), ErrorCode(0) com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after statement closed.   at** sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_45]   at 

以下是课程:

public class DAOConnectionFactory {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(DAOConnectionFactory.class);
    private static final String databaseJNDI = "jdbc/presencedb";
    private static DataSource dataSource = null;
    private static Context context = null;
    private static Connection conn = null;

    private DAOConnectionFactory() {
        System.out.println("Initialized");
    }

    private static DataSource getDataSource() {
        if (dataSource != null) {
            return dataSource;
        }
        try {
            context = new InitialContext();

            if (context == null) {
                context = new InitialContext();
            }

            dataSource = (DataSource) context.lookup("java:comp/env/" + databaseJNDI);
        } catch (NamingException e) {
            logger.error("Error while creating datasource.", e);
        }
        return dataSource;
    }

    protected static Connection getConnection() {
        try {
            conn = getDataSource().getConnection();
        } catch (SQLException e) {
            logger.error("Error while getting database connection.", e);
        }
        return conn;
    }

    protected static void closeConnection(Connection connection, Statement statement, ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                logger.error("Error while closing resultset.", e);
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                logger.error("Error while closing statement.", e);
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                logger.error("Error while closing connection.", e);
            }
        }
    }
}

hikaricp属性:

cachePrepStmts="true" 
defaultAutoCommit="true" 
description="Presence database." 
driverClassName="com.mysql.jdbc.Driver" 
factory="com.zaxxer.hikari.HikariJNDIFactory" 
global="jdbc/presencedb" 
jdbcUrl="jdbc:mysql://192.168.254.167/presence" 
maxWaitMillis="10000" maximumPoolSize="30" 
name="jdbc/presencedb" 
password="" 
prepStmtCacheSize="50" 
prepStmtCacheSqlLimit="512" 
removeAbandoned="true" 
removeAbandonedTimeout="300" 
type="javax.sql.DataSource" 
idleTimeout="25200000"
maxLifetime="25200000"
username="root"

添加这是我获取连接的方式

Connection connection = null;
PreparedStatement preparedStatement = null;
connection = DAOConnectionFactory.getConnection();
preparedStatement = connection.prepareStatement(SQL_UPDATE);

DAOConnectionFactory.closeConnection(connection, preparedStatement, null);

这种情况总是在我执行负载测试时发生,否则几个随机查询我没有注意到这一点。 HikariCP版本为2.4.1。

1 个答案:

答案 0 :(得分:1)

不要声明Connection静态,它们会在压力测试或分布式环境中导致冲突,最终的代码看起来像

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import com.itextpdf.text.log.LoggerFactory;

public class DAOConnectionFactory {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(DAOConnectionFactory.class);
    private static final String databaseJNDI = "jdbc/presencedb";
    private static DataSource dataSource = null;
    private static Context context = null;
    private Connection conn = null;

    public DAOConnectionFactory() {
        System.out.println("Initialized");
    }

    static {
        if (dataSource == null) {
            try {
                context = new InitialContext();

                if (context == null) {
                    context = new InitialContext();
                }

                dataSource = (DataSource) context.lookup("java:comp/env/" + databaseJNDI);
            } catch (NamingException e) {
                logger.error("Error while creating datasource.", e);
            }
        }
    }

    public Connection getConnection() {
        try {
            conn = dataSource.getConnection();
        } catch (SQLException e) {
            logger.error("Error while getting database connection.", e);
        }
        return conn;
    }

    protected static void closeConnection(Connection connection, Statement statement, ResultSet resultSet) {
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                logger.error("Error while closing resultset.", e);
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                logger.error("Error while closing statement.", e);
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                logger.error("Error while closing connection.", e);
            }
        }
    }
}

这样的电话
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Main {

    public static String SQL_UPDATE = "query";

    public DAOConnectionFactory factory = new DAOConnectionFactory();

    public static void main(String args[]){
        Main instanceppl = new Main();
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        connection = instanceppl.factory.getConnection();
        try {
            preparedStatement = connection.prepareStatement(SQL_UPDATE);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        instanceppl.factory.closeConnection(connection, preparedStatement, null);

    }

}