为什么一段时间后丢失了Mysql连接池?

时间:2015-06-09 08:02:52

标签: java mysql tomcat

我的应用程序同时使用Mysql和Postgres,Web服务器是tomcat 7.0。应用程序运行一段时间后,如15,16小时,它丢失了mysql连接池,并且我在日志中收到“无法获取连接,池错误超时等待空闲对象”错误消息。所以我需要启动tomcat重启应用程序再次重新连接到Mysql连接池。我完成查询后关闭每个连接。这种情况永远不会发生在Postgres上,只是在Mysql上,所以......很奇怪。

我使用Singleton连接到Mysql和Postgres的连接池。下面是Mysql的代码。

public class DB {
    private static DB database = new DB();
    private DataSource ds;

    private DB() {
        try {
            InitialContext ic = new InitialContext();
            ds = (DataSource)ic.lookup("java:comp/env/jdbc/mobile_recharge");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static DB getInstance() {
        return database;
    }

    public DataSource getDS() throws SQLException {
        return ds;
    }
}

其中一个查询:

public boolean preSaveData(HashMap<String, String> mapXML, String date, String serialNum) {
    try {
        con = open();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        log.writeLog(mapXML.get("terminalId"), mapXML.get("date_time"), "fails to insert order info into mysql: " + e.getMessage());
        return false;
    }

    String table = new JudgeTidField().table(mapXML.get("tidField"));

    String query = "insert into " + table + " (Terminal_id, Yewu, Phone_number, Company, " + 
                   "Order_money, Balance, Actual_money, Order_record_date, Recharge_record_date, Province, Serial_number) values " +
                   "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";

    try {
        presta = (PreparedStatement) con.prepareStatement(query);
        presta.setString(1, mapXML.get("terminalId"));
        presta.setString(2, "recharge");
        presta.setString(3, mapXML.get("phoneNum"));
        presta.setString(4, mapXML.get("type"));
        presta.setFloat(5, Float.parseFloat(mapXML.get("price")));
        presta.setFloat(6, (float) 0.000);
        presta.setFloat(7, Float.parseFloat(mapXML.get("actualMoney")));
        presta.setString(8, date);
        presta.setString(9, date);
        presta.setString(10, mapXML.get("province"));
        presta.setString(11, serialNum);

        presta.executeUpdate();
        log.writeLog(mapXML.get("terminalId"), mapXML.get("date_time"), "success to insert order info into mysql");
        return true;
    } catch (SQLException e) {
        e.getMessage();
        log.writeLog(mapXML.get("terminalId"), mapXML.get("date_time"), "fail to insert order info into mysql: " + e.getMessage());
        return false;
    } finally {
        try {
            presta.close();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }

        try {
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}

在context.xml中:

<Context  docBase="Mobile" path="/Mobile" reloadable="true">
  <Resource
    name="jdbc/mobile_recharge"
    auth="Container"
    type="javax.sql.DataSource"
    maxActive="500"
    maxIdle="5"
    maxWait="5000"
    driverClassName="com.mysql.jdbc.Driver"
    username="root"
    password="xxxxxxxx"
    url="jdbc:mysql://xxx.xxx.x.xxx:3306/mobile_recharge?characterEncoding=utf8" />

  <Resource
    name="jdbc/pgsql"
    type="javax.sql.DataSource"
    maxActive="500"
    maxIdle="2"
    username="postgres"
    maxWait="5000"
    driverClassName="org.postgresql.Driver"
    password="xxxxxxxx"
    url="jdbc:postgresql://xxx.xxx.x.xxx:5555/runningacounts"/>
</Context>

在web.xml中:

<resource-ref> 
  <description>MysqlDB Connection</description> 
  <res-ref-name>jdbc/mobile_recharge</res-ref-name> 
  <res-type>javax.sql.DataSource</res-type> 
  <res-auth>Container</res-auth> 
</resource-ref>
<resource-ref> 
  <description>PGDB Connection</description> 
  <res-ref-name>jdbc/pgsql</res-ref-name> 
  <res-type>javax.sql.DataSource</res-type> 
  <res-auth>Container</res-auth> 
</resource-ref>

1 个答案:

答案 0 :(得分:0)

至少对于MySQL,我建议你研究连接池验证和清理选项,特别是validationQuerytestWhileIdletestOnBorrowtimeBetweenEvictionRunsMillis,{{1} },removeAbandoned等 - 此处有更多详细信息:http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#Common_Attributes

我在Tomcat中通过JDBC与MySQL连接有类似的问题,这些属性的合理应用解决了它,因此在长时间闲置后不需要反弹Tomcat。希望有所帮助。