許多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.請任何人都可以讓我知道問題出在哪裏。
感謝您的回答。當我一個接一個地運行JDBC調用(沒有ExecutorService)時,DB中沒有這種「事務中的IDLE」連接。這不是說,在JDBC調用或池配置中沒有問題嗎?我以很多方式嘗試了我的代碼,最後一個改變是改變了使用Executor的這些任務的運行方式,而在沒有的情況下,我發現IDLE在事務中作爲序列運行時不會出現。 –
不客氣。如果沒有關於正在做什麼的更多細節(您正在運行的查詢,您正在使用的DBMS),我認爲我不會有太多幫助,但看起來您對查詢有一個併發問題。這篇文章(http://serverfault.com/questions/660642/what-could-cause-idle-in-transaction-in-a-pentaho-pdi-process)描述了一個類似的問題,並提出問題可能在代碼本身,例如正在開始的事務並且從未完成。請注意,如果您按順序運行事務,則可能不會出現此類問題,因爲它似乎是您的情況。 –