ActiveRecord :: StatementInvalid:PG InFailedSqlTransaction

unt*_*wal 66 postgresql activerecord ruby-on-rails rollback pg

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

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

关于这个问题的任何想法的人.

B S*_*ven 93

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

问题在于,当Postgres引发异常时,它会对同一连接上的未来事务进行中毒.

解决方法是回滚违规交易:

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

  raise e
end
Run Code Online (Sandbox Code Playgroud)

参考文献.

  • 请不要从"异常"中解救,如下所述:/sf/ask/703372141/异常是Ruby的异常层次结构的根,所以当您拯救Exception时,您可以从一切事物中解脱出来,包括SyntaxError,LoadError和Interrupt等子类. (12认同)
  • 在 Rails [AR::Transactions 手册](http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#module-ActiveRecord::Transactions::ClassMethods-label-Exception+handling+and +回滚+返回) (2认同)
  • @adantj 当你立即重新加注时,拯救异常是完全可以的;正如给定答案中所做的那样 (2认同)

Fur*_*han 81

我有这个问题.只需重新启动Rails服务器即可

  • 我刚刚遇到这个问题并重新启动服务器确实修复了它.有人对这种行为有解释吗? (7认同)
  • 我在测试环境中遇到了同样的问题(rspec 引发错误)。`rake db:drop` + `rake db:create` + `rake db:migrate` 解决了这个问题。也许我搞砸了迁移。 (2认同)

Ted*_*dom 14

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

我正在使用database_cleaner gem,并将其配置为不在事务中包含测试,如果他们使用javascript.因此,为了解决这个问题,我添加js: true了导致此问题的每个规范.(即使认为规范实际上并没有使用javascript,这是确保测试不会包含在事务中的最方便的方法.但我确信这样做的方法不那么简单).

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

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
Run Code Online (Sandbox Code Playgroud)

如果你不使用database_cleaner,则可能是测试将被包裹在交易的理由是,该use_transactional_fixtures选项设置为truespec/spec_helper.rb.尝试将其设置为false.


Wil*_*rry 8

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

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


lob*_*ati 5

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