在我的 UWSGI Flask 应用程序中,我遇到如下间歇性错误:
数据库错误:(psycopg2.DatabaseError) 错误,没有来自 libpq 的消息
ResourceClosedError:此结果对象不返回行。它已自动关闭。
NoSuchColumnError:“无法在行中找到列“my_table.my_column_name_that_exists”的列”
数据库错误:(psycopg2.DatabaseError)“D”消息中的数据不足...与服务器失去同步:获取消息类型“2”,长度 740303471
在我的 postgresql 日志中,我看到:警告:已经有一个事务正在进行中
刷新 Flask 中的网页通常可以解决该错误。
以下是我重现该错误所采取的步骤:
- 停止应用程序
sudo service postgresql restart
- 启动应用程序
- 导航到我的 Flask 应用程序中执行多个同时查询的网页
- 预期行为:未记录数据库错误
- 实际行为:出现上面列出的一个或多个错误
我尝试增加 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
最佳答案
这些错误是数据库连接被多个线程或进程错误共享的症状。
默认情况下,uwsgi 在 wsgi 文件中创建应用程序后 fork 进程。如果应用程序创建创建了可以重复使用的数据库连接,则您可能最终会得到具有损坏数据库状态的 fork 进程。要在 uwsgi 中解决此问题,有以下选项:
- 在创建应用程序之前不要创建数据库连接,或者
- 使用
--lazy-apps
选项调用 uwsgi,这会在创建应用程序之前将 uwsgi 更改为 fork
lazy-apps
模式会对性能产生负面影响(请参阅 preforking vs lazy-apps vs lazy ),因此在应用创建期间避免使用数据库通常是更好的选择。
感谢 univerio 在评论中对此进行解释。
关于postgresql - UWSGI Flask SQLAlchemy 间歇性 PostgreSQL 错误,错误为 "WARNING: there is already a transaction in progress",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43648075/