ExecutorService导致JDBC连接问题

时间:2015-09-17 14:51:11

标签: java jdbc

许多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.请任何人都能告诉我问题所在。

1 个答案:

答案 0 :(得分:2)

您的问题中没有代码可以打开与数据库的任何连接。因此,很难提出答案。但是,由于您声明您正在使用连接池,因此您应该更好地查看池配置参数,因为它们规定了空闲连接在被驱逐之前可以打开多长时间。例如,如果您在tomcat中运行连接池,则应特别注意" minIdle"," maxIdle"和" minEvictableIdleTimeMillis"属性。见https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html