2015-07-11 173 views
3

在我的項目中,我有一些傳統的插件。這些插件用於PostgreSQL的只讀查詢。大多數插件運行良好,但其他部分非常慢。這是停止從C3P0獲取連接的原因。 它看起來像連接超時的更改沒有效果。如何用JDBC取消PostgreSQL中長時間運行的查詢?

如何設置有效取消這些查詢的超時時間? 我認爲服務器端的超時可以是很好的解決方案,但我不想在配置中爲所有服務器設置超時。另外我不想丟棄這個連接,只需要取消當前查詢。

你能分享你對這個問題的解決方案的想法嗎?

+0

來自不同線程的Statement.cancel()'對我來說工作正常。 –

回答

3

如果您動態設置配置參數statement_timeout,則此參數僅影響當前會話: 如果執行的查詢長於給定時間,則會取消而不丟失連接。

test=# set statement_timeout to 1000; -- 1s 
SET 
test=# select pg_sleep(5);    -- 5s 
ERROR: canceling statement due to statement timeout 
test=# set statement_timeout to 0;  -- turn off 
SET 

更新 - 控制Postgres進程的方法的簡要概述。

你可以列出一個服務器的所有正在運行的進程:

test=# select pid, query_start, state, query from pg_stat_activity; 
pid |  query_start   | state |       query 
------+----------------------------+--------+-------------------------------------------------------------- 
4004 | 2015-07-12 20:50:01.033+02 | active | select pid, query_start, state, query from pg_stat_activity; 

例如,該查詢列出查詢,這執行時間超過5分鐘:

select * 
from pg_stat_activity 
where state = 'active' 
and now() - query_start > '5m'; 

您可以手動取消長時間運行的查詢:

select pg_cancel_backend(pid); 

或終止進程:

select pg_terminate_backend(pid); 

您可以運行一個程序,該程序會自動取消長時間運行的查詢。 它可能是後臺進程(daemon)或可能與cron執行。

這個查詢會自動取消查詢其執行時間長於5分鐘:

select pg_cancel_backend(pid) 
from pg_stat_activity 
where state = 'active' 
and now() - query_start > '5m'; 

當然,這種自動化解決方案必須非常謹慎與後果充分認識實施。

更多文檔:pg_stat_activity,pg_cancel_backend()

+0

嘿! thx點我吧!它是新的插件很好的解決方案,但我不能在我的傳統插件中使用它:(我可以多次設置此參數爲相同的值多次,而無需清理一個連接?我有一個想法,但我應該檢查它 – ivanenok

+1

你可以改變參數可以根據需要多次設置,但不需要重複設置參數爲相同的值,一旦設置,參數的值將應用於所有後續查詢,直到它被更改。 – klin

1

經過對@glin的postgres行爲的一些研究和暗示,我已經解決了我的問題。 c3p0連接池用於傳統插件。我已經找到了將自定義擴展添加到池行爲的功能。

http://www.mchange.com/projects/c3p0/#user_extensions_to_configurations

有默認的C3P0提供initSql擴展。這樣我們可以把命令

設置statement_timeout爲1000;

在您的配置文件中,它將在您的源代碼沒有任何改變的情況下工作。所有你需要的只是重建你的插件jar!