每当我们部署Rails / Postgres应用程序并且迁移是部署的一部分时,我们会收到以下错误:
PG :: InFailedSqlTransaction:错误:当前事务被中止, 命令被忽略,直到事务块结束
PG :: FeatureNotSupported:错误:缓存计划不得更改结果 型
违规的SQL事务通常是不同的。
我想知道在部署时是否有办法防止这种情况发生?
答案 0 :(得分:0)
准备好的陈述经过兑现以提高绩效。 每当在涉及的表的模式发生更改后使用预准备语句时,您将获得:
PG::FeatureNotSupported: ERROR: cached plan must not change result type
PG的适配器通常通过优雅地DEALLOCATE
准备好的声明来恢复。
但是,如果事务中发生错误,则事务已经失败。 DEALLOCATE
语句在同一事务中运行,因此将回滚。
所以连接留下了一个不起作用的兑现准备语句。
Disable prepared statements。可能会或可能不会导致性能下降:
# config/database.yml
production:
prepared_statements: false
将following monkey patch添加到ActiveRecord::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
这可以确保如果在事务中出现错误,则先关闭事务,然后清除缓存,然后重试事务一次。如果由于某种原因您不想重试交易,可以删除super
块内的rescue
来电。