postgresql - 将rails应用程序部署到heroku时经常看到PG::InFailedSqlTransaction错误

标签 postgresql ruby-on-rails-4 heroku

每当我们部署 Rails/Postgres 应用程序并且迁移是部署的一部分时,我们都会收到以下错误:

PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block

PG::FeatureNotSupported: ERROR: cached plan must not change result type

有问题的 SQL 事务通常是不同的。

我想知道是否有办法在我们部署时防止这种情况发生?

最佳答案

原因:

兑现准备好的报表是为了提高性能。 每当在更改相关表的架构后使用准备好的语句时,您将得到:

PG::FeatureNotSupported: ERROR: cached plan must not change result type

PG 的适配器通常可以通过 DEALLOCATE 正常恢复。正在准备的声明。

但是,如果错误发生在事务中,则事务已经失败。 DEALLOCATE 语句在同一事务内运行,因此会回滚。 因此,连接留下了一个不起作用的兑现准备好的报表。

解决方案:

  • 问题解决后升级到 Rails 5.0.4+ there .
  • 运行迁移时不要运行任何 Rails 进程。如果您希望零停机部署,则不适用。适用,但如果您有多个应用程序访问同一数据库,则不方便。
  • Disable prepared statements共。可能会也可能不会导致性能下降:

    # config/database.yml
    
    production:
      prepared_statements: false
    
  • 添加following monkey patchActiveRecord::Base (略有修改的版本):

    # config/initializers/rails_recoverable_transactions.rb
    
    raise "Remove monkey patch in #{__FILE__}" if Rails::VERSION::MAJOR > 4
    
    module TransactionRecoverable
      module ClassMethods
        def transaction(*args)
          super(*args) do
            yield
          end
        rescue PG::InFailedSqlTransaction
          connection.rollback_db_transaction
          connection.clear_cache!
    
          super(*args) do
            yield
          end
        end
      end
    end
    
    class << ActiveRecord::Base
      prepend TransactionRecoverable::ClassMethods
    end
    

这可以确保,如果您在事务中遇到上述错误,则首先关闭事务,然后清除缓存,然后重试事务一次。如果由于某种原因您不想重试交易,您可以删除 rescue block 内的 super 调用。

关于postgresql - 将rails应用程序部署到heroku时经常看到PG::InFailedSqlTransaction错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37217661/

相关文章:

ruby-on-rails - Rails 依赖哪些选项是可能的?

ruby-on-rails - compass 未在某些文件中导入扩展名

node.js - heroku推送被拒绝无法编译node.js应用程序

java - Hibernate @Filter 枚举集合

PostgreSQL 12.3 : ERROR: out of memory for query result

java - 如何使用mybatis在postgres中将int[]映射到integer[]

ruby-on-rails - 如何通过 gem OmniAuth Facebook/Twitter 注销社交网站

postgresql - 如何断开 Postgrex 连接?

ruby-on-rails - Rails 引擎不自动加载带有命名空间的模型

python - Django Heroku postgres 连接错误