25

完全なエラーは

ActiveRecord::StatementInvalid: Mysql2::Error: SAVEPOINT active_record_1 does not exist: ROLLBACK TO SAVEPOINT active_record_1

単体テストを作成していますが、新しいActiveRecordオブジェクトを作成しようとすると、このエラーが発生しますが、特定のポイントの後でのみ発生します。これは、次の行の後に発生します。

ActiveRecord::Base.connection.execute "DROP TABLE IF EXISTS foo"
ActiveRecord::Base.connection.execute "CREATE TABLE foo (id INTEGER PRIMARY KEY)"

(テストが成功すると、テーブル'foo'にデータが入力されます)

上記の行の前に、私は次のようなものを書くことができます

User.create(email => 'foo@bar.com')

そして、すべてが正常に動作します。ただし、を呼び出した後に上記の行を書き込もうとすると、上記のようActiveRecord::Base.connection.executeになりSAVEPOINT errorます。また、executeステートメントをトランザクション内に配置しようとしましたが、それは役に立ちませんでした。私は困惑しています。

参考までに-私はRails3.2.8を使用しています

4

6 に答える 6

27

Mysql DDEステートメント(テーブルの作成/削除/切り捨て)を使用しているため、暗黙のコミットが発生します。

暗黙的なコミットのため、現在のトランザクションのすべてのセーブポイントが削除されます(上記のドキュメントを参照)。

これを回避するには、トランザクションをオフにして、 DatabaseCleaner(切り捨てモード)を使用します。

于 2012-12-05T20:52:33.443 に答える
6

この問題を解決するには..

config.use_transactional_fixtures = false

于 2013-06-13T06:14:04.903 に答える
3

テーブルを作成/削除するときに「TEMPORARY」を使用できます。

http://dev.mysql.com/doc/refman/5.1/en/implicit-commit.html TEMPORARYキーワードが使用されている場合、ALTER TABLE、CREATE TABLE、およびDROPTABLEはトランザクションをコミットしません。(これは、コミットを引き起こすCREATE INDEXなどの一時テーブルに対する他の操作には適用されません。)ただし、暗黙的なコミットは発生しませんが、ステートメントをロールバックすることもできません。したがって、このようなステートメントを使用すると、トランザクションの原子性に違反します。たとえば、CREATE TEMPORARY TABLEを使用してからトランザクションをロールバックすると、テーブルは存在したままになります。

于 2013-03-28T21:02:27.863 に答える
2

明確にするために。MySql DDEステートメントをトリガーするテストを独自のファイルに分離してから、そのファイルに詰め込むことができconfig.use_transactional_fixtures = falseます。これにより、他のすべてのテストが影響を受けることはありません。これで、分離されたテストファイルのクリーンアップを担当します。

于 2014-04-03T16:28:04.973 に答える
0

私は私を助けた次のリンクを見つけました:

于 2012-11-06T08:00:28.790 に答える
0

まず、DBクリーニング戦略を選択できるDatabaseCleanergemがインストールされていることを確認します。私たちが受け取っているエラーは、truncation戦略を使用するのが最善であることを意味します。

# file: Gemfile

group :test do
  gem ‘database_cleaner’
end

DatabaseCleaner構成をfeaturesディレクトリに追加します(以下を参照)。

#file: features/support/database_cleaner.rb

begin
  require 'database_cleaner'
  require 'database_cleaner/cucumber'

  DatabaseCleaner.strategy = :truncation
rescue NameError
  raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
end

Around do |scenario, block|
  DatabaseCleaner.cleaning(&block)
end
于 2019-01-30T09:51:09.440 に答える