2010-11-13 60 views
2

我正在使用psycopg2作爲我正在處理的cherrypy應用程序,並且clog & phpgadmin可以手動處理某些操作。這裏的Python代碼:Psycopg/Postgres:連接隨機掛出

#One connection per thread 
cherrypy.thread_data.pgconn = psycopg2.connect("...") 
... 
#Later, an object is created by a thread : 
class dbobj(object): 
def __init__(self): 
    self.connection=cherrypy.thread_data.pgconn 
    self.curs=self.connection.cursor(cursor_factory=psycopg2.extras.DictCursor) 
... 
#Then, 
try: 
blabla 
self.curs.execute(...) 
self.connection.commit() 
except: 
self.connection.rollback() 
lalala 
... 
#Finally, the destructor is called : 
def __del__(self): 
self.curs.close() 

我在與任何psycopg或者Postgres的一個問題(altough我認爲後者的可能性更大)。在發送了幾個查詢後,我的連接就完蛋了。同樣,phpgadmin - 通常也會被丟棄;它提示我在多次提出請求後重新連接。只有CLI保持不變。

問題是,這些都是非常隨機發生的,我甚至無法找到原因。我可以在幾頁請求後鎖定,或者在請求數百頁之後從未真正遇到任何問題。我在Postgres裏發現的唯一的錯誤日誌,之後終止應用程序是:

... 
LOG: unexpected EOF on client connection 
LOG: could not send data to client: Broken pipe 
LOG: unexpected EOF on client connection 
... 

我想每一個新dbobj實例被創建時創建一個新的連接,但我絕對不想做這個。

另外,我讀過一個可能遇到類似的問題,除非所有的事務都提交了:我對每一個INSERT/UPDATE查詢都使用try/except塊,但是我從來沒有用過它作爲SELECT查詢,我也不想寫更多的樣板代碼(順便說一句,他們需要承諾嗎?)。即便如此,爲什麼phpgadmin會關閉?

max_connections在.conf文件中設置爲100,所以我不認爲這也是原因。一個櫻桃工人只有10個線程。

有沒有人有一個想法,我應該先看看?

回答

0

儘管我不知道爲什麼成功的SELECT查詢會阻止連接,但在幾乎每一個不需要與另一個查詢結合使用的查詢都能解決問題之後,溢出.commit()

0

確切地看到你在哪裏填充和訪問cherrypy.thread_data有點困難。我建議您調查psycopg2.pool.ThreadedConnectionPool,而不是試圖將一個conn綁定到每個線程。

1

Psycopg2在每個事務(包括SELECT查詢)後都需要提交或回滾,或者它將連接保留爲「IDLE IN TRANSACTION」。這在文檔中現在是一個警告:

警告:默認情況下,任何查詢執行(包括簡單的SELECT)都會啓動一個事務:對於長時間運行的程序,如果不採取進一步操作,會話將保持「空閒在交易中「,由於多種原因(會話鎖定,表格膨脹......),這是一種不理想的情況。對於長期存在的腳本,請確保儘快終止事務或使用自動提交連接。