繁体   English   中英

ActiveRecord::StatementInvalid: PG InFailedSqlTransaction

[英]ActiveRecord::StatementInvalid: PG InFailedSqlTransaction

我正在尝试创建一个 ActiveRecord Object。但是我在创建它时遇到了这个错误。

(0.1ms)  ROLLBACK
ActiveRecord::StatementInvalid: PG::InFailedSqlTransaction: ERROR:  current transaction is       aborted, commands ignored until end of transaction block

关于这个问题的任何想法。

其他答案都没有解决问题的根本原因

问题在于,当 Postgres 引发异常时,它会毒害同一连接上的未来事务。

修复方法是回滚有问题的事务:

begin
  ActiveRecord...do something...
rescue Exception => e
  puts "SQL error in #{ __method__ }"
  ActiveRecord::Base.connection.execute 'ROLLBACK'

  raise e
end

请参阅参考资料

我有这个问题。 只需重新启动 Rails 服务器,它应该可以工作

这个问题发生在我的测试环境中,并且是由于每个测试都包含在自己的事务中。

我正在使用 database_cleaner gem,并将其配置为如果他们使用 javascript,则不会将测试包装在事务中。 所以为了解决这个问题,我在每个导致这个问题的规范中添加了js: true (即使规范实际上并未使用 javascript,这是确保测试不会包含在事务中的最方便的方法。不过,我相信这样做的黑客式方法较少)。

作为参考,这里是来自spec/support/database_cleaner.rb的 database_cleaner 配置:

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.clean_with :deletion
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :deletion
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

如果您没有使用 database_cleaner,那么测试被包装在事务中的原因可能是use_transactional_fixtures选项在spec/spec_helper.rb中设置为true 尝试将其设置为 false。

你可以在 postgresql 日志中看到真正发生的事情,我花了很多时间去挖掘这个问题,最后发现我们滥用 upsert gem 导致 PG 错误,只有在 postgresql 日志中才有真正的信息。

https://github.com/seamusabshere/upsert/issues/39

在我的规范中引用不再存在的列时,我遇到了这个错误。 确保您的数据库是最新的,并且您的代码不需要一个不存在的列。

问题:

  1. 程序执行了错误的 SQL 语句。 错误的 SQL 语句是问题的根本原因。
  2. 错误的 SQL 语句后,程序不会立即回滚或释放 SAVEPOINT。
  3. 程序在错误的 SQL 语句后执行 SQL 语句。
  4. PostgreSQL引发错误:当前事务被中止,命令被忽略直到事务块结束

解决方案:

找出不正确的 SQL 语句并更正它。 如果不想更正 SQL 语句,请在错误的 SQL 语句后使用 ROLLBACK 或 RELEASE SAVEPOINT。

就我而言,我收到此错误只是因为我没有 rake'd 我的测试数据库。

在我的情况下,/usr/local/ dmy /usr/local/var/postgres/postgresql.conf国际格式

将日期类型更改为美国格式的mdy为我解决了这个问题。

将 Rails 从 4.2.2 升级到 4.2.5 后遇到类似问题我不得不升级pg gem 并且问题开始发生

9) WorkPolicy#is_publicly_viewable? is publicly visible hides work if deleted
     Failure/Error: before { DatabaseCleaner.clean_with :deletion }
     ActiveRecord::StatementInvalid:
       PG::InFailedSqlTransaction: ERROR:  current transaction is aborted, commands ignored until end of transaction block
       :             SELECT tablename
                   FROM pg_tables
                   WHERE schemaname = ANY (current_schemas(false))

从这个意义上说, Teddy Widom 的答案是正确的,只是总结问题:

有时,当您使用DatabaseCleaner.clean_with :deletion时,您可能会干扰 PostgreSQL 事务。

所以对我来说,解决方案是在由DatabaseCleaner.clean_with :truncation引起的部分测试中替换DatabaseCleaner.clean_with :deletion

谷歌搜索的人还有一件事。 如果您注意到此堆栈跟踪:

An error occurred in an `after(:context)` hook.
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "table_rows" does not exist
LINE 1: ...ion_schema.tables WHERE table_schema = 'test' AND table_rows...
^

...可能是由这个问题引起的

我遇到了那个问题。 我发现这是我的查询。 这意味着当我在不指定表列的情况下进行关联查询时。 前任:

class Holiday < ApplicationRecord
     belongs_to :company
end

class Company < ApplicationRecord
    has_many :timeoffs
end

在假日模型中我查询

company.timeoffs.where("(start_date <= ? and end_date >= ?) and id != ?", begin_date, begin_date, 1)

发生错误是因为我没有指定哪个表的id在我将代码更改为后它对我有用

company.timeoffs.where("(start_date <= ? and end_date >= ?) and time_offs.id != ?", begin_date, begin_date, 1)

为了解决这个问题,我跑了

tail -f /usr/local/var/log/postgres.log

然后只需复制错误并查看日志文件中的输出即可。

运行 Rspec 时出现此错误。 在 yml 文件中添加 4 条消息以进行翻译后,我无法察觉到这种情况的发生。

运行: rails db:drop db:create db:schema:load RAILS_ENV=test

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM