ActiveRecord::Base.transaction do
Foo.new.bar
end
Foo.new.baz
Can I determine programmatically from within the bar()
or baz()
methods if a transaction is already taking place? Looking for something that might look like
ActiveRecord::Base.within_transaction?
, that would return true
when called from bar()
and false
when called for baz()
.
In case it is relevant, I'm using a mysql database with the mysql2 gem, and am ok with a solution that works only for mysql.
You can use
ActiveRecord::Base.connection.open_transactions
to see if your method is executed in a transaction.
ActiveRecord::Base.connection.open_transactions == 0
implies that your method is not executed in a transaction. Anything greater than 0 would imply that your method is executed in a transaction. For example ActiveRecord::Base.connection.open_transactions > 0
Update:
from rails documentation
all database statements in the nested transaction block become part of the parent transaction
So number of open transaction will be one even if you are in a nested transaction.
This is what i got in my 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