2011-11-20 10 views
10

私はPostgreSQL 9.1/PostGIS 1.5、psycopg2 2.4.2、pgbouncer 1.4.2でDjango 1.3を実行しています。pgbouncer - 閉じる理由:すべての接続で汚れたサーバ

2011-11-20 02:15:25.027 29538 LOGのS-0x96c2200:私はpgbouncer.logでログエントリを取得し、データベースへのすべての単一の接続で

app_db/[email protected] :5432クローズのため:不正なサーバー(年齢= 0)。

私はこの問題の解決策を見つけることができません - なぜ誰かがアイデアを持っていますか?私はpgbouncer(セッション/トランザクションモード、別のタイムアウトなど)を再設定しようとしましたが、無駄です。

答えて

15

私はこれを理解したと思います。問題はDjangoとPsycopg2の長年の問題です。基本的に、Psycopg2はBEGIN文をDBに自動的に発行します。ただし、Djangoがデータ変更が発生していないと判断した場合、トランザクション終了時にCOMMITは発行されません。

この問題の解決策がいくつかあります。詳細はhttp://www.slideshare.net/OReillyOSCON/unbreaking-your-django-applicationをご覧ください。自動コミットを無効にするのが理想的です(DB設定でautocommit = Trueを設定すると、命名規則が面倒です)。これにより、読み取り専用の関数だけでなく書き込み関数でもトランザクションが防止されるため、これらの関数を@commit_on_successデコレータで手動でラップする必要があります。

また、ミドルウェアクラスにdjango.middleware.transaction.TransactionMiddlewareを追加するだけです。これにより、トランザクション内のすべての要求がラップされます。これは、トランザクション内の読み取り専用要求を不必要にラップすることを意味しますが、すばやく解決策です。

+0

ちょうどいい方法を見つけました。警告:バックグラウンドタスク処理にセロリなどを使用している場合は、これを行わないでください。非同期で実行されているタスクにオブジェクトの主キーを渡す競合状態が発生する可能性があります。要求が完了する前(およびトランザクションがコミットされる)にタスクが実行され、タスクがオブジェクトを見つけることができません。私はこれに対する唯一の解決策は手動トランザクション管理だと思います。 – Dick

+1

私のプレゼンテーションにリンクしてくれてありがとうというだけのメモ...私は役に立つとうれしいです! :) – Christophe

+0

もちろん!素晴らしいプレゼンテーションでした。 Djangoのトランザクション管理が「壊れている」ことはほとんど知られていないことがわかりました。 – Dick

関連する問題