3

私は現在取り組んでいるチェリーピーアプリにpsycopg2を使用し、いくつかの操作を手動で処理するためにcliとphpgadminを使用しています。Pythonコードは次のとおりです。

#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 のいずれかに問題があります (ただし、後者の可能性が高いと思います)。いくつかのクエリを送信した後、接続が切断されます。同様に、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 に設定されているため、それも理由ではないと思います。1 つの cherrypy ワーカーには 10 個のスレッドしかありません。

私が最初にどこを見ればいいのか、誰にも考えがありますか?

4

3 に答える 3

2

Psycopg2 では、SELECT クエリを含むすべてのトランザクションの後にコミットまたはロールバックが必要です。そうしないと、接続が「IDLE IN TRANSACTION」のままになります。これは現在、ドキュメントの警告です:

警告: デフォルトでは、単純な SELECT を含むすべてのクエリの実行によってトランザクションが開始されます。長時間実行されるプログラムの場合、それ以上のアクションが実行されない場合、セッションは「トランザクションでアイドル状態」のままになります。これは、いくつかの理由から望ましくない状態です (ロックはセッションによって保持され、テーブルが肥大化します...)。存続期間の長いスクリプトの場合は、できるだけ早くトランザクションを終了するか、自動コミット接続を使用してください。
于 2016-10-19T22:23:00.277 に答える
0

どこにデータを入力してアクセスしているのかを正確に把握するのは少し困難ですcherrypy.thread_datapsycopg2.pool.ThreadedConnectionPool1 つの conn を各スレッドに自分でバインドしようとするのではなく、調査することをお勧めします。

于 2010-11-14T04:42:18.673 に答える
0

SELECT成功したクエリが接続をブロックする理由はわかり.commit()ませんが、別のクエリと連携して動作する必要のないほぼすべてのクエリの後にこぼれると、問題が解決しました。

于 2010-11-17T14:12:27.270 に答える