2015-09-17 90 views
0

許多JDBC調用(查詢DB並獲取結果)通過ExecutorService執行。我發現,當這些調用被執行時,即使連接正確關閉,JDBC連接也需要很長時間才能關閉連接。爲什麼我這麼說呢,當通過JMeter運行負載測試時,數據庫顯示許多連接在IDLE in transaction中。如果運行測試的線程數很高,則交易中閒置的連接數量會增加。如果測試運行緩慢,則連接會慢慢關閉(1,2分鐘),這意味着在事務中存在IDLE連接,但幾分鐘後它們將變爲空閒狀態。我也在這裏使用連接池。如果我將JDBC查詢函數作爲序列(一個接一個地)運行,那麼數據庫不會在事務中的IDLE中顯示任何連接。以下是我如何運行運行JDBC查詢的可運行任務。 TaskManager類處理整個ExecutorService相關的功能。ExecutorService導致JDBC連接問題

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中沒有任何連接中的空閒。

我使用java 7.請任何人都可以讓我知道問題出在哪裏。

回答

2

在你的問題中沒有任何代碼打開到數據庫的任何連接。因此,很難提出答案。但是,由於您聲明您正在使用連接池,因此您應該更好地查看池配置參數,因爲它們指定在可拆卸驅逐之前閒置連接可能會打開多長時間。例如,如果您在tomcat中運行連接池,則應特別注意「minIdle」,「maxIdle」和「minEvictableIdleTimeMillis」屬性。請參閱https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

+0

感謝您的回答。當我一個接一個地運行JDBC調用(沒有ExecutorService)時,DB中沒有這種「事務中的IDLE」連接。這不是說,在JDBC調用或池配置中沒有問題嗎?我以很多方式嘗試了我的代碼,最後一個改變是改變了使用Executor的這些任務的運行方式,而在沒有的情況下,我發現IDLE在事務中作爲序列運行時不會出現。 –

+0

不客氣。如果沒有關於正在做什麼的更多細節(您正在運行的查詢,您正在使用的DBMS),我認爲我不會有太多幫助,但看起來您對查詢有一個併發問題。這篇文章(http://serverfault.com/questions/660642/what-c​​ould-cause-idle-in-transaction-in-a-pentaho-pdi-process)描述了一個類似的問題,並提出問題可能在代碼本身,例如正在開始的事務並且從未完成。請注意,如果您按順序運行事務,則可能不會出現此類問題,因爲它似乎是您的情況。 –