我的应用程序同时使用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>
答案 0 :(得分:0)
至少对于MySQL,我建议你研究连接池验证和清理选项,特别是validationQuery
,testWhileIdle
,testOnBorrow
,timeBetweenEvictionRunsMillis
,{{1} },removeAbandoned
等 - 此处有更多详细信息:http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#Common_Attributes
我在Tomcat中通过JDBC与MySQL连接有类似的问题,这些属性的合理应用解决了它,因此在长时间闲置后不需要反弹Tomcat。希望有所帮助。