【问题标题】:pgbouncer - closing because: unclean server on every connectionpgbouncer - 关闭,因为:每个连接上的服务器不干净
【发布时间】:2012-01-02 04:40:57
【问题描述】:

我正在运行带有 PostgreSQL 9.1/PostGIS 1.5、psycopg2 2.4.2 和 pgbouncer 1.4.2 的 Django 1.3。

在每次连接到数据库时,我都会在 pgbouncer.log 中获得一个日志条目:

2011-11-20 02:15:25.027 29538 LOG S-0x96c2200: app_db/postgres@192.168.171.185:5432 关闭,因为:服务器不干净(年龄=0)。

我找不到这个问题的任何解决方案 - 有人知道为什么吗?我尝试重新配置 pgbouncer(会话/事务模式、不同的超时等),但无济于事。

【问题讨论】:

    标签: django postgresql psycopg2 pgbouncer


    【解决方案1】:

    好的,我想我已经弄清楚了。问题在于 Django 和 Psycopg2 的长期问题。基本上,Psycopg2 会自动向数据库发出 BEGIN 语句。但是,如果 Django 认为没有发生数据修改,它不会在事务结束时发出 COMMIT。

    这个问题有几个解决方案,查看http://www.slideshare.net/OReillyOSCON/unbreaking-your-django-application了解更多详情。理想情况下,您关闭自动提交(通过在数据库设置中设置 autocommit = True,尴尬的命名约定)。这可以防止只读函数以及写入函数的事务,因此您需要手动将这些函数包装在 @commit_on_success 装饰器中。

    或者,只需将 django.middleware.transaction.TransactionMiddleware 添加到您的中间件类中。这会将每个请求包装在事务中。这也意味着在事务中不必要地包装只读请求,但这是一个快速而肮脏的解决方案。

    【讨论】:

    • 好吧,只是发现了困难的方式,警告:如果您使用 celery(或其他东西)进行后台任务处理,请不要这样做。可能会有竞争条件,您将对象的主键传递给运行异步的任务。任务可以在请求完成(并且事务提交)之前开始运行,因此任务找不到对象。我认为唯一的解决方案是手动事务管理。
    • 只是一个说明,感谢您链接到我的演示文稿...我很高兴它很有用! :)
    • 当然!这是一个很棒的介绍;我发现对 Django 中的“损坏”事务管理知之甚少,这令人震惊。
    • 我不明白你为什么用引号括起来。 Django 的事务管理坏了
    • 这很有帮助!很棒的演示文稿@Cristophe。我立即执行了您的建议。一件模糊的事情:设置数据库 autocommit=True 是否会影响管理列表/编辑/创建视图,或者他们是否手动管理事务并自行破解,无论是否启用事务中间件 & autocommit=True?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    • 2017-03-03
    相关资源
    最近更新 更多