UWSGI Flask SQLAlchemy Intermittent PostgreSQL错误“警告:已经有正在进行的事务”

时间:2017-04-27 03:19:18

标签: postgresql flask sqlalchemy uwsgi

在我的UWSGI Flask应用程序中,我遇到如下的间歇性错误:

  • DatabaseError: (psycopg2.DatabaseError) error with no message from the libpq
  • ResourceClosedError: This result object does not return rows. It has been closed automatically.
  • NoSuchColumnError: "Could not locate column in row for column 'my_table.my_column_name_that_exists'"
  • DatabaseError: (psycopg2.DatabaseError) insufficient data in "D" message...lost synchronization with server: got message type "2", length 740303471

在我的postgresql日志中,我看到:WARNING: there is already a transaction in progress

刷新烧瓶中的网页通常可以解决错误。

以下是重现错误的步骤:

  1. 停止申请
  2. sudo service postgresql restart
  3. 启动应用程序
  4. 导航到我的烧瓶应用中的网页,该网页会同时执行多个查询
    • 预期行为:未记录数据库错误
    • 实际行为:上面列出的一个或多个错误发生
  5. 我尝试增加postgresql日志记录的详细程度以及似乎不适当的虚拟交易共享,例如:以下显示虚拟事务2/53的所有日志条目,并对应于上述错误:

    process 8548 session 5901589a.2164 vtransaction 2/53 LOG:  statement: BEGIN
    process 8548 session 5901589a.2164 vtransaction 2/53 LOG:  statement: SELECT 1
    process 8548 session 5901589a.2164 vtransaction 2/53 LOG:  statement: SELECT my_table.id AS my_table_id, ... 
        FROM my_table 
        WHERE my_table.id = 'my_id' 
         LIMIT 1
    process 8548 session 5901589a.2164 vtransaction 2/53 LOG:  statement: BEGIN
    process 8548 session 5901589a.2164 vtransaction 2/53 WARNING:  there is already a transaction in progress
    process 8548 session 5901589a.2164 vtransaction 2/53 LOG:  statement: SELECT 1
    process 8548 session 5901589a.2164 vtransaction 2/53 LOG:  statement: SELECT my_other_table.id AS my_other_table_id, ...
        FROM my_other_table
        WHERE 'my_other_id' = my_other_table.id
    process 8548 session 5901589a.2164 vtransaction 2/53 LOG:  statement: SELECT my_table.id AS my_table_id, ... 
        FROM my_table 
        WHERE my_table.id = 'my_id' 
         LIMIT 1
    process 8548 session 5901589a.2164 vtransaction 2/53 LOG:  statement: ROLLBACK
    

1 个答案:

答案 0 :(得分:1)

这些错误是多个线程或进程错误地共享数据库连接的症状。

默认情况下,uwsgi在wsgi文件中创建应用程序后分叉进程。如果应用程序创建创建了可能重用的数据库连接,则可能最终会出现具有损坏的数据库状态的分叉进程。要在uwsgi中解决此问题,可以选择:

  1. 在创建应用程序之后才创建数据库连接, OR
  2. 使用--lazy-apps选项调用uwsgi,在创建应用程序之前将uwsgi更改为fork
  3. lazy-apps模式会产生负面的性能影响(请参阅preforking vs lazy-apps vs lazy),因此在应用创建期间避免使用数据库通常是更好的选择。

    感谢univerio在评论中解释这一点。