[英]Rails 4: PG::InFailedSqlTransaction when testing a rake task with RSpec
[英]How can I avoid PG::InFailedSqlTransaction when adding new columns?
我们针对同一个数据库运行两个rails应用程序。 部署时,我们通常部署到App A,然后部署到App B,在部署期间重新启动所有rails进程。 App A在7台服务器上运行,至少有20个进程连接到数据库。 App B在4台服务器上运行,至少有8个与数据库的连接。
今天,当我们部署App A时,我们在现有表中添加了一列:
change_table :organizations do |t|
t.integer :users_count, default: 0
end
我们希望这很好:它在现有表上的新列,它有一个默认值。 迁移运行后不久,App A(重启之前)和App B(部署之前)出现了一些错误。
这些错误是:
FATAL ActiveRecord::StatementInvalid error: PG::InFailedSqlTransaction:
ERROR: current transaction is aborted, commands ignored until end of
transaction block
在postgres日志中,我有58个错误,如下所示:
postgres[12283]: ERROR: cached plan must not change result type
postgres[12283]: STATEMENT: SELECT "organizations".* FROM
"organizations" WHERE "organizations"."id" = $1 LIMIT $2
这会重复多次,并在所有部署完成并重新启动所有进程后消失。
似乎Rails错误#12330和Rails PR 22170在Rails 5.0中解决了这个问题,但我有这个提交,我仍然看到这个错误。
相关软件版本
关于Rails bug#12330的一条评论表明我必须添加具有null默认值的列。 另一个建议执行多个部署,一个用于禁用prepare语句,另一个用于执行迁移并重新启用预准备语句。
有没有避免这种情况? 当我们重新启动服务器时它会清除,但我觉得我错过了一些东西 - 比如只使用可空列可能会一起避免这些错误。 这不会在每次部署时发生,我不知道如何重现它 - 但这不是第一次发生。
您已经更改了表结构,因此更改了准备好的SELECT返回的内容,因为您使用"organizations".*
,并返回所有列。 PostgreSQL显然不支持更新预准备语句,因此您需要创建新会话(重新连接)或使用DEALLOCATE删除准备好的语句。
编辑:你也可以停止使用SELECT *
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.