【发布时间】:2016-04-11 02:09:11
【问题描述】:
我正在使用 jersey 2.0 创建一个 RESTful web 服务,它使用 Tomcat 连接池连接到一个 mysql 数据库。我遇到了一个问题,当我将 maxActive 连接设置为大于 1 的任何值时,我在大约 15 个后续请求调用后收到以下错误消息。
数据源拒绝建立连接,来自服务器的消息:“连接太多”
我对池的理解是,它将创建配置的最大连接数,然后开始重用这些连接,并根据需要提供它们。我最初怀疑代码中存在泄漏,但经过审查后我不确定问题可能是什么。当 maxActive 设置为 1 时,问题不会发生。
这是我的代码。
public DatabaseManager(Properties connProps){
this.connProps = connProps;
this.createConnection();
this.createTableRepository();
}
public void createConnection()
{
try {
Context context = new InitialContext();
Context envCtx = (Context)context.lookup("java:comp/env");
this.dataSource = new DataSource();
PoolProperties props = new PoolProperties();
props.setUrl(this.connProps.getProperty("url"));
props.setUsername(this.connProps.getProperty("username"));
props.setPassword(this.connProps.getProperty("password"));
props.setDriverClassName(this.connProps.getProperty("driverClassName"));
props.setMaxActive(Integer.parseInt(this.connProps.getProperty("maxActive")));
this.dataSource.setPoolProperties(props);
} catch (NamingException e) {
}
}
private void createTableRepository()
{
this.tableRepository = new TableRepository();
Connection connection = null;
ResultSet rs = null;
try {
connection = getPooledConnection();
DatabaseMetaData dbMeta = (DatabaseMetaData)connection.getMetaData();
rs = dbMeta.getTables(null, null, "%s", null);
while(rs.next()){
String tableName = rs.getString(3);
TableMeta table = new TableMeta(tableName);
ResultSet columns = dbMeta.getColumns(null, null, tableName, null);
while(columns.next()){
table.addColumn(columns.getString(4));
}
this.tableRepository.addTable(tableName, table);
}
} catch (SQLException e) {
e.printStackTrace();
}
finally{
if(rs != null){
try{
rs.close();
rs = null;
}
catch(SQLException e){}}
if(connection != null){
try{
connection.close();
connection = null;
}
catch(SQLException e){}}
}
}
private void executeStatement(IDBQuery dbQuery)
{
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
int rows = 0;
try {
connection = this.dataSource.getConnection();
statement = connection.prepareStatement(dbQuery.toString());
if(dbQuery instanceof DBQuerySelect){
rs = statement.executeQuery();
if(rs != null){
dbQuery.populateQueryResuls(rs);
}
}
else {
rows = statement.executeUpdate();
if(rows > 0){
dbQuery.populateQueryResults(rows);
}
}
if(rs != null){
rs.close();
}
if(statement != null){
statement.close();
}
if(connection != null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
finally {
if(rs != null){try{rs.close(); rs = null;}catch(SQLException e){}}
if(statement != null){try{statement.close(); statement = null;}catch(SQLException e){}}
if(connection != null){try{connection.close(); connection = null;}catch(SQLException e){}}
}
}
public Connection getPooledConnection(){
Connection con = null;
try {
con = this.dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
我用两种方法调用连接,每一种方法都关闭 finally 块中的 ResultSet、Statement 和 Connection 以保证它们被关闭。我不知道什么可能导致连接最大化。
我正在使用 mysql-connector-java-5.1.38.jar 进行连接。
非常感谢任何帮助。
【问题讨论】:
-
你在哪里打电话给
createConnection()?getPooledConnection()的代码在哪里?你从哪里打电话给executeStatement()? -
感谢 Gergely 的回复。我添加了方法 getPooledConnection() 和 executeStatement();
-
感谢 Gergely 的评论。我添加了缺少的方法。我正在从 DatabaseManager 类的构造函数中调用 createConnection。
标签: java mysql tomcat jdbc connection-pooling