在mysql连接超时后无法从apache DBCP连接池获得连接

时间:2013-12-20 07:46:26

标签: java mysql java-ee jdbc database-connection

这是非常奇怪的情况,我认为它在处理mysql连接对象时最常见。以下是场景

在执行sql语句之前,我使用apache DBCP连接池获取连接对象。一切正常,直到mysql连接超时(8小时)发生。所以在这个连接池之后没有返回任何连接对象,这使得任何sql操作都等到下一次重启tomcat服务器。如果没有DBCP,我们可能会收到communicationException,表示没有发送或接收的数据包。这就是我选择apache DBCP认为它将管理连接池的原因。以下是我的代码

import javax.sql.DataSource;
import org.apache.log4j.Logger;
import org.apache.commons.dbcp.BasicDataSource;

DataSource dataSource
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(driver);
ds.setUsername(username);
ds.setPassword(password);
ds.setUrl(url + "/" + dbname);
dataSource = ds;
logger.info("Getting connection from DBCP connection pool...");
con = dataSource.getConnection();
logger.info("MYSQL DB Connection Creation Successful...");

我注意到apache DBCP正在使用单例模式来创建连接,因此每次请求时都不会创建新的连接对象。如果我做错了什么,请建议我出路并澄清我。我不是以下解决方案

  • 增加mysql超时(bcoz mysql很常见,我不认为增加会是一个很好的解决方案)
  • 发生问题时重新启动tomcat服务器(不是一个漂亮的解决方案,因为我们不能总是那里,也没有脚本......)。

请建议我出路。感谢

2 个答案:

答案 0 :(得分:1)

我没有在您的代码中获取DBCP connectionn池的设置。只需尝试下面的连接池代码,如文档中所述。

PoolProperties p = new PoolProperties();
          p.setUrl("jdbc:mysql://localhost:3306/mysql");
          p.setDriverClassName("com.mysql.jdbc.Driver");
          p.setUsername("root");
          p.setPassword("password");
          p.setJmxEnabled(true);
          p.setTestWhileIdle(false);
          p.setTestOnBorrow(true);
          p.setValidationQuery("SELECT 1");
          p.setTestOnReturn(false);
          p.setValidationInterval(30000);
          p.setTimeBetweenEvictionRunsMillis(30000);
          p.setMaxActive(100);
          p.setInitialSize(10);
          p.setMaxWait(10000);
          p.setRemoveAbandonedTimeout(60);
          p.setMinEvictableIdleTimeMillis(30000);
          p.setMinIdle(10);
          p.setLogAbandoned(true);
          p.setRemoveAbandoned(true);
          p.setJdbcInterceptors(
            "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"+
            "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");
          DataSource datasource = new DataSource();
          datasource.setPoolProperties(p);

          Connection con = null;
          try {
            con = datasource.getConnection();
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery("select * from user");
            int cnt = 1;
            while (rs.next()) {
                System.out.println((cnt++)+". Host:" +rs.getString("Host")+
                  " User:"+rs.getString("User")+" Password:"+rs.getString("Password"));
            }
            rs.close();
            st.close();
          } finally {
            if (con!=null) try {con.close();}catch (Exception ignore) {}
          }

还会阅读有关此document中每个属性的信息。 希望这能解决你的问题

答案 1 :(得分:0)

需要查看异常。然而,只是在黑暗中拍摄: 如果你看到像

这样的东西
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException

您可能希望使用try / catch包装它并在catch块中重新连接并重新运行查询。 检查MySQL docs是否处理停止的连接。

BTW:使用Spring非常简单 - 您可以配置dataSource以恢复停滞的连接。