一整天的谷歌搜索这个问题让我比以往更加困惑,所以我呼吁SO寻求帮助。我正在尝试使用池化连接到mysql DB,但我显然误解了一些东西。下面是来自应用程序的代码片段,该代码扫描文件夹以查找代表“作业”的新目录;找到后,将为找到的每个文件夹创建数据库对象。我将_insert()方法基于我在SO上找到的模式。我的理解是连接已正确关闭并返回到连接池。但是,我注意到,添加8个对象后,代码将挂起在getConnection()上。我发现默认的活动连接数是8,所以我添加了调试行,我将活动连接数限制为2.果然,在代码挂起之前只添加了两个对象。
发生了什么事?我需要更改什么才能使这些连接被释放并添加回池中?我发现one post提到了PoolableConnection类,但我对文档以及我发现的其他大多数示例似乎都没有使用它感到困惑。
Scanner类,它根据磁盘上特定目录中的文件夹在数据库中创建Job对象:
public class Scanner extends Thread {
public void run() {
syncJobs();
}
void syncJobs(List<String> folderNames) {
for (String folderName : folderNames) {
Job job = addJobToDB(folderName);
}
}
Job addJobToDB(String folderName ) {
Job job = new Job();
job.name = folderName;
job.save();
return job;
}
}
所有对象都有一个抽象基类(每个对象都覆盖_insert):
public abstract class DBObject {
private final int insert() {
return _insert();
}
public final void save() {
if (id == 0)
id = insert();
else
update();
}
}
还有实际的Job对象(只显示了insert方法):
public class Job extends DBObject {
public int _insert() {
String query = "insert into jobs (name) values (?)";
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
int id = 0;
try {
conn = Database.getConnection();
ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, id);
ps.executeUpdate();
rs = ps.getGeneratedKeys();
rs.next();
id = rs.getInt(1);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(ps);
DbUtils.closeQuietly(conn);
}
return id;
}
}
最后,提供连接的Database对象:
import org.apache.commons.dbcp.BasicDataSource;
public final class Database {
private static final BasicDataSource dataSource = new BasicDataSource();
static {
dataSource.setUrl("jdbc:mysql://localhost:3306/dbName?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
dataSource.setUsername("user");
dataSource.setPassword("****");
// This line added for debugging: sure enough, only 2 objects are created.
dataSource.setMaxActive(2);
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}