2013-11-20 1 views
21
ActiveRecord::Base.transaction do 
    Foo.new.bar 
end 
Foo.new.baz 

取引が既に行われている場合、bar()またはbaz()の方法からプログラムで決定することはできますか? ActiveRecord::Base.within_transaction?のようなものを探すと、baz()が呼び出されたときbar()falseから呼び出されたときにはtrueが返されます。ruby​​ on railsのデータベーストランザクション内に既に存在するかどうかを確認するには?

関連性のあるケースでは、mysql2 gemでmysqlデータベースを使用していますが、mysqlのみで動作するソリューションで問題ありません。

答えて

30

あなたのメソッドがトランザクション内で実行されたかどうかを確認するために

ActiveRecord::Base.connection.open_transactions 

を使用することができます。

ActiveRecord::Base.connection.open_transactions == 0は、トランザクションでメソッドが実行されないことを示します。 0より大きい値は、メソッドがトランザクション内で実行されることを意味します。例えばActiveRecord::Base.connection.open_transactions > 0

更新:レールのドキュメントから

all database statements in the nested transaction block become part of the parent transaction

ので、開いているトランザクションの数は、ネストされたトランザクション内にある場合でも、いずれかになります。

これは私が

ActiveRecord::Base.transaction do 
    User.first.update_attribute(:first_name, "something") 
    ActiveRecord::Base.transaction do 
     User.first.update_attribute(:last_name, "something") 
     p ActiveRecord::Base.connection.open_transactions 
    end 
end 


    (0.3ms) BEGIN 
    User Load (0.8ms) SELECT "users".* FROM "users" LIMIT 1 
    (0.8ms) UPDATE "users" SET "first_name" = 'something', "updated_at" = '2013-11-20 18:33:52.254088' WHERE "users"."id" = 1 
    User Load (0.5ms) SELECT "users".* FROM "users" LIMIT 1 
    (0.4ms) UPDATE "users" SET "last_name" = 'something', "updated_at" = '2013-11-20 18:33:52.266976' WHERE "users"."id" = 1 
    1 
    (14.2ms) COMMIT 
    => 1 
+0

私のコンソールで得たものであり、あなたのコードは 'config.use_transactional_fixtures = true'にして、テストで実行する場合は、あなたが1つのトランザクション深いですか? C-; – Phlip

+1

@Phlip:私の更新があなたの質問に答えることを願っています – usha

関連する問題