StatementInvalidedSqlTransaction

我正在尝试创建一个 ActiveRecord 对象,但是在创建它的时候出现了这个错误。

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

大家对这个问题有什么想法吗。

50543 次浏览

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

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

我使用 database _ clean gem,并将其配置为如果测试使用 javascript,则不在事务中包装测试。因此,为了解决这个问题,我将 js: true添加到导致这个问题的每个规范中。(即使规范实际上并没有使用 javascript,这也是确保测试不会被包装在事务中的最方便的方法。不过,我相信还有更少的黑客式的方法可以做到这一点)。

作为参考,下面是来自 spec/support/database_cleaner.rb的 database _ clean 配置:

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 _ clean,那么将测试包装在事务中的原因可能是 use_transactional_fixtures选项在 spec/spec_helper.rb中设置为 true。试试把它设为假。

我花了很多时间研究这个问题,最后发现我们误用了 upsert gem 导致了 PG 错误,只有在 postgreql 日志中才有关于这个问题的真实信息

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

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

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

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

解决办法是回滚违规事务:

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


raise e
end

参见 参考文献

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

可能是由这个问题引起的

问题:

  1. 程序执行错误的 SQL 语句。错误的 SQL 语句是问题的根源。
  2. 程序不会在错误 SQL 语句之后立即执行 ROLLback 或 RELEASE SAVEPOINT。
  3. 程序在错误的 SQL 语句之后执行 SQL 语句。
  4. PostgreSQL 引发 ERROR: 当前事务中止,直到事务块结束时忽略命令

解决方案:

查找不正确的 SQL 语句并纠正它。 如果不希望更正 SQL 语句,请在错误的 SQL 语句后使用 ROLLback 或 RELEASE SAVEPOINT。

在我的例子中,我收到这个错误仅仅是因为我没有耙过我的测试 db。

在我的案例中,/usr/local/var/postgres/postgresql.conf的 Postgres 配置将数据类型作为 dmy的国际格式

改变日期类型为美国格式的 mdy固定这个问题为我。

我有这个问题。 我发现这是我的疑问。 它意味着在不指定表列的情况下使用关联查询。 例如:

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

然后只需要复制错误并观察日志文件中的输出。