ActiveRecord :: StatementInvalid:PG InFailedSqlTransaction

时间:2014-01-15 13:05:48

标签: ruby-on-rails postgresql activerecord rollback pg

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

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

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

10 个答案:

答案 0 :(得分:89)

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

问题在于,当Postgres引发异常时,它会对同一连接上的未来交易造成毒害。

修复方法是回滚违规交易:

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

  raise e
end

请参阅reference

答案 1 :(得分:79)

我有这个问题。只需重启Rails服务器即可正常工作

答案 2 :(得分:14)

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

我正在使用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选项在true中设置为spec/spec_helper.rb。尝试将其设置为false。

答案 3 :(得分:8)

你可以看到postgresql日志中真正发生了什么,我花了很多时间来深入研究这个问题,最后发现我们误用upsert gem导致PG错误,只有在postgresql日志中才有真正的信息是什么的继续

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

答案 4 :(得分:5)

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

答案 5 :(得分:2)

问题:

  1. 程序执行不正确的SQL语句。不正确的SQL语句是问题的根本原因。
  2. 在错误的SQL语句后,程序不会立即ROLLBACK或RELEASE SAVEPOINT。
  3. 程序在错误的SQL语句之后执行SQL语句。
  4. PostgreSQL引发错误:当前事务中止,命令被忽略,直到事务块结束
  5. 解决方案:

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

答案 6 :(得分:2)

在我的情况下,我收到此错误只是因为我没有耙掉我的测试数据库。

答案 7 :(得分:2)

就我而言,/usr/local/var/postgres/postgresql.conf的Postgres配置的日期类型为dmy的国际格式

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

答案 8 :(得分:0)

将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 Answer在这个意义上是正确的,只是为了总结问题:

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

因此,我的解决方案是在DatabaseCleaner.clean_with :deletion

引起的部分测试中替换DatabaseCleaner.clean_with :truncation

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

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...
^

......可能是由这个问题造成的

答案 9 :(得分:0)

我遇到了这个问题。 我发现这是我的疑问。 这意味着当我使用关联查询而不指定表列时。 例如:

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)