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

È possibile determinare a livello di programmazione dai metodi bar() o baz() se una transazione è già in corso? Alla ricerca di qualcosa che potrebbe sembrare ActiveRecord::Base.within_transaction?, che restituirebbe true quando chiamato da bar() e false quando chiamato per baz().Come dire se già all'interno di una transazione di database in ruby ​​on rails?

Nel caso sia rilevante, sto usando un database mysql con mysql2 gem e sto bene con una soluzione che funziona solo per mysql.

risposta

30

È possibile utilizzare

ActiveRecord::Base.connection.open_transactions 

per vedere se il metodo viene eseguito in una transazione.

ActiveRecord::Base.connection.open_transactions == 0 implica che il metodo non viene eseguito in una transazione. Qualunque cosa maggiore di 0 implicherebbe che il tuo metodo sia eseguito in una transazione. Per esempio ActiveRecord::Base.connection.open_transactions > 0

Aggiornamento:

dalla documentazione rotaie

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

Così numero di transazione aperta sarà uno anche se si è in una transazione annidata.

questo è quello che ho ottenuto nella mia console

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

e se il codice viene eseguito in un test con 'config.use_transactional_fixtures = true', allora siete voi una transazione più profondo? C-; – Phlip

+1

@Phlip: spero che il mio aggiornamento risponda alla tua domanda – usha