2012-09-25 47 views
2

AFAIK,PostgreSQL 8.3不支持事務超時。我已經閱讀了關於未來支持該功能的內容,並且有一些關於它的討論。但是,由於具體原因,我需要針對此問題的解決方案。因此,我所做的是定期運行的腳本:基於以檢索所需的時間太長,並保持最老的(trxTimeOut.sql)進行交易的ProcessID鎖和活動,查詢PostgreSQL的事務超時解決方法

1):在此基礎上查詢

SELECT procpid 
FROM 
(
    SELECT DISTINCT age(now(), query_start) AS age, procpid 
    FROM pg_stat_activity, pg_locks 
    WHERE pg_locks.pid = pg_stat_activity.procpid 
) AS foo 
WHERE age > '30 seconds' 
ORDER BY age DESC 
LIMIT 1 

2),殺死相應的進程(trxTimeOut.sh):

psql -h localhost -U postgres -t -d test_database -f trxTimeOut.sql | xargs kill 

雖然我已經測試過它,似乎工作,我想知道這是一種可以接受的方法,還是應該考慮換一種方法?

+0

是升級到至少8.4版的選項?如果是這樣,您可以使用pg_terminate_backend()來終止打開的連接。 –

+0

感謝您的回答。不幸的是,我不能認爲這種升級是理所當然的(不依賴於我)。無論如何,pg_terminate_backend()只會是比kill命令更好的結束連接的方式,對吧?我的意思是,查詢+殺死(或終止)解決方案是相對可接受的? –

回答

3

PostgreSQL 8.3支持在語句級別超時。雖然它不完全是一個事務超時,因爲它不計算在同一事務的前一個語句中花費的時間,但它通常足以滿足避免客戶端卡住任何查詢的實際目的。

要自動中止,如果任何聲明的時間超過10秒的交易:

SET statement_timeout=10000; 
+0

謝謝,但問題稍微複雜一點。如果客戶端應用程序。由於某種原因掛起(即與Java Swing事件相關,但與需要太長時間的語句無關),這可能最終阻止其他客戶端,因爲第一個客戶端授予了一些鎖(在未提交/回滾事務中)第二個正在等待訪問。該腳本殺死了第一筆交易,因爲花費的時間太長,無論問題的根源如何(因此允許第二個客戶端繼續)。 statement_timeout只會中止第二個客戶端的事務(因爲鎖定) –

+1

'statement_timeout'不能解決「事務處於空閒」狀態,這仍然可以防止日誌重放。有一些非常具體的案例,這個答案不夠好。 –