【问题标题】:ActiveRecord::StatementInvalid: PG InFailedSqlTransactionActiveRecord::StatementInvalid: PG InFailedSqlTransaction
【发布时间】:2014-02-03 23:14:24
【问题描述】:

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

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

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

【问题讨论】:

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


【解决方案1】:

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

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)

【讨论】:

    【解决方案2】:

    其他答案都不能解决问题的根本原因

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

    解决方法是回滚有问题的事务:

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

    reference

    【讨论】:

    • Rails 中也提到过AR::Transactions manual
    • 请不要从Exception 中拯救,如此处所述:stackoverflow.com/questions/10048173/… Exception 是 Ruby 异常层次结构的根,所以当你拯救 Exception 时,你会从所有东西中拯救出来,包括诸如 SyntaxError 之类的子类,加载错误和中断。
    • 在我粘贴链接的评论中,它清楚地说明了您的代码存在问题和部分错误建议的原因。该链接还提供了其他信息。你的“为什么不呢?”评论没有意义,除非您没有阅读评论或链接或两者兼而有之。我会问你同样的事情,如果你不花时间思考你的问题和答案,那为什么还要发布它们?
    • @adantj 当你立即重新加注;正如给定答案中所做的那样
    • 使用raise ActiveRecord::Rollback 回滚帮助了我。也供参考api.rubyonrails.org/classes/ActiveRecord/Transactions/…
    【解决方案3】:

    在我的情况下,/usr/local/var/postgres/postgresql.conf 的 Postgres 配置的日期类型为 dmy 的国际格式

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

    【讨论】:

      【解决方案4】:

      在我的情况下,我收到这个错误仅仅是因为我没有 rake'd 我的测试数据库。

      【讨论】:

        【解决方案5】:

        问题:

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

        解决方案:

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

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

            我遇到了这个问题。只需重新启动 Rails 服务器,它就可以工作了

            【讨论】:

            • 我刚遇到这个问题,实际上重新启动服务器确实解决了这个问题。有人对此行为有解释吗?
            • 我在测试环境中遇到了同样的问题(rspec 抛出错误)。 rake db:drop + rake db:create + rake db:migrate 解决了这个问题。也许我搞砸了迁移。
            • 正在 Rails 控制台中进行测试。重新加载还不够,需要重新启动控制台。谢谢!
            • 这不是一个可行的解决方案,当服务应该自主运行时,重新启动服务器不是一个选项。问题是PG连接状态不好,需要重新连接或者需要执行ROLLBACK退出当前事务。
            • 升级到 PG12 和 Ruby 2.6.6 后,我发生了这种情况。我使用 rvm,升级到 2.6.6 需要为新 gemset 重建 pg gem。 rake db:test:prepare 不起作用 - 但 RAILS_ENV=test rake db:drop db:create db:migrate 解决了问题。
            【解决方案8】:

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

            【讨论】:

              【解决方案9】:

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

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

              【讨论】:

              • 该链接没有多大帮助,但检查 postgres 日志的想法完全没有帮助。就我而言,这是一个未准备好的测试数据库。谢谢!
              【解决方案10】:

              这个问题发生在我的测试环境中,是因为每个测试都包装在自己的事务中。

              我使用的是 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,那么测试被包装在事务中的原因可能是spec/spec_helper.rb 中的use_transactional_fixtures 选项设置为true。尝试将其设置为 false。

              【讨论】:

              • 如果您禁用事务性固定装置而不插入诸如 DatabaseCleaner 之类的东西,那么您的测试数据库将继续堆积每次运行的数据。您可以为集成规范设置它,而不是为每个无法按预期工作的规范设置js: true。请记住,使用:deletion 而不是:transaction 要慢得多,因此在可行的情况下最好使用事务。
              • 至此,我发现 DB 清理器相对于默认事务测试增加了复杂性(也就是弹出更多错误)。但我的问题是我在同一个it 块中有两个请求,例如get ...。将其移出修复了此错误。
              • 我不认为添加js: true 是解决此问题的最佳方法。它没有解决问题,删除策略非常慢。通过切换到事务策略,我将测试速度提高了 2.5 倍。请参阅下面的答案。
              猜你喜欢
              • 2018-03-08
              • 1970-01-01
              • 1970-01-01
              • 2017-06-18
              • 2014-02-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多