许多JDBC调用(查询数据库和获取结果)都是通过ExecutorService执行的。我发现当执行这些调用时,即使这些连接正确关闭,JDBC连接也需要很长时间才能关闭连接。为什么我这么说,当通过JMeter运行负载测试时,数据库显示许多连接都在IDLE in transaction
中。如果运行测试的线程数很高,则事务中空闲时的连接数会增加。如果测试运行缓慢,则连接缓慢关闭(1,2分钟),这意味着事务中IDLE中存在连接,但几分钟后它们变为IDLE。我也在这里使用连接池。如果我将JDBC查询功能作为一个序列(一个接一个地)运行,那么数据库不会在事务中显示IDLE中的任何连接。下面是我运行运行JDBC查询的runnable任务的方法。 TaskManager类处理整个ExecutorService相关的函数。
public class TaskManager {
final private ThreadServiceFactory threadFactory;
private int concurrentThreadCount;
private ExecutorService executerSV;
private final CountDownLatch latch;
// I keep a count of proposed tas task as servicecount
public TaskManager(int serviceCount) {
threadFactory = new ThreadServiceFactory();
this.concurrentThreadCount = serviceCount;
latch = new CountDownLatch(serviceCount);
}
public void execute( ThreadService runnableTask) {
Object rv = null;
runnableTask.setCountDownLatch(latch);
if(executerSV == null) {
executerSV = Executors.newFixedThreadPool(this.concurrentThreadCount, getThreadFactory());
}
executerSV.execute(runnableTask);
}
public boolean holdUntilComplete(){
try {
latch.await();
executerSV.shutdown();
return true;
} catch (InterruptedException e) {
e.printStackTrace();
return false;
}
}
private ThreadServiceFactory getThreadFactory(){
threadFactory.setDeamon( Boolean.FALSE);
return threadFactory;
}
}
在我的测试课上;
public void test(){
TaskManager tm = new TaskManager(3);
tm.execute(queryTask1);
tm.execute(queryTask2);
tm.holdUntilComplete();
}
queryTask1是一个Runnable,它调用JDBC select查询。
如果我运行queryTask1.run(); queryTask2.run();
,则DB中的连接中没有任何IDLE。
我使用java 7.请任何人都能告诉我问题所在。
答案 0 :(得分:2)
您的问题中没有代码可以打开与数据库的任何连接。因此,很难提出答案。但是,由于您声明您正在使用连接池,因此您应该更好地查看池配置参数,因为它们规定了空闲连接在被驱逐之前可以打开多长时间。例如,如果您在tomcat中运行连接池,则应特别注意" minIdle"," maxIdle"和" minEvictableIdleTimeMillis"属性。见https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html