简体   繁体   English

MySQL超时到期后,c3p0的连接引发异常

[英]Connection of c3p0 throws exception after MySQL timeout expired

I use c3p0 library of version 0.9.2.1 for creating a connection pool in a web application. 我使用版本0.9.2.1的c3p0库在Web应用程序中创建连接池。 After MySQL timeout I get exception: MySQL超时后,我得到异常:

"HTTP Status 500 - The last packet successfully received from the server was 627 301 milliseconds ago. The last packet sent successfully to the server was 627 302 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem." “ HTTP状态500-从服务器成功收到的最后一个数据包是627301毫秒之前。成功发送到服务器的最后一个数据包是627302毫秒之前。比服务器配置的'wait_timeout'值长。您应该考虑这两个到期和/或在用于您的应用程序之前测试连接的有效性,增加服务器为客户端超时配置的值,或使用Connector / J连接属性'autoReconnect = true'来避免此问题。”

I tried to append an autoReconnect parameter to JDBC url but there is no effect as well. 我试图将autoReconnect参数附加到JDBC url,但是也没有任何效果。 So, in that way I use connection pool in my application: 因此,通过这种方式,我在应用程序中使用了连接池:

For testing I have set wait_timeout of MySQL to 180 sec 为了进行测试,我将MySQL的wait_timeout设置为180秒

set @@global.wait_timeout=180;

show global variables like "wait_timeout";

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  |  180  |
+---------------+-------+

and further there are next pieces of code 以及接下来的几段代码

c3p0.properties c3p0.properties

# JDBC paramters are ommited
# Basic pool configuration
c3p0.initialPoolSize=5
c3p0.minPoolSize=5
c3p0.maxPoolSize=50
c3p0.acquireIncrement=5
# Managing connection age
c3p0.maxConnectionAge=100
c3p0.maxIdleTime=90
# Configuring connection testing
c3p0.idleConnectionTestPeriod=30
c3p0.testConnectionOnCheckin=true
c3p0.preferredTestQuery=SELECT 1

DBConnectionUtil.java DBConnectionUtil.java

public class DBConnectionUtil {
    // initialized through c3p0.properties
    private static ComboPooledDataSource ds = new ComboPooledDataSource();

    public static ComboPooledDataSource getConnectionPool() {
        return ds;
    }

    public static void destroyConnectionPool() {
        ds.close();
    }

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}

UserDAO.java UserDAO.java

public class UserDAO {

    private Connection connection;

    public UserDAO() throws SQLException {
        connection = DBConnectionUtil.getConnection();
    }

    public User find(Integer id) throws SQLException {
        User user = null;
        PreparedStatement ps = connection.prepareStatement("SELECT * FROM `USERS` WHERE ID = ?");
        ps.setInt(1, id);
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            user = new User();
            user.setId(rs.getInt("ID"));
            user.setName(rs.getString("NAME"));
            user.setUsername(rs.getString("USERNAME"));
            user.setPassword(rs.getString("PASSWORD"));
            user.setParentId(rs.getInt("PARENT_ID"));
        }
        rs.close();
        ps.close();
        return user;
    }
}

DAOUtil.java DAOUtil.java

public class DAOUtil {
    private static UserDAO userDAO;

    public static UserDAO getUserDAO() {
        return userDAO;
    }

    static {
        try {
            userDAO = new UserDAO();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

After expired MySQL wait_timeout, for instance, when I call DAOUtil.userDAO.find(id) it throws exception which was described above. 例如,在过期的MySQL wait_timeout之后,当我调用DAOUtil.userDAO.find(id)时,它将引发上面描述的异常。

Could you help me to realize what I'm doing wrong, please? 您能帮我意识到我在做错什么吗? Note: I can't change MySQL ini file. 注意:我无法更改MySQL ini文件。

Try to close connection in your Dao class and ask for new one from connection pool for every request to database. 尝试关闭您的Dao类中的连接,并为每个对数据库的请求从连接池中请求一个新的连接。

Connection con;
try {
  con=DBConnectionUtil.getConnection();
  //some code here
} finally {
  if(con!=null){
      con.close();
  } 

And it's not safe to have Connection as a object field, better to use it as a local variable, because connection is not thread safe. 而且,将Connection作为对象字段是不安全的,最好将其用作局部变量,因为Connection不是线程安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM