Подтвердить что ты не робот

Как узнать, уже ли в транзакции базы данных в рубине на рельсах?

ActiveRecord::Base.transaction do
  Foo.new.bar
end
Foo.new.baz

Могу ли я определить программно из методов bar() или baz(), если транзакция уже происходит? Ищете что-то, что может выглядеть ActiveRecord::Base.within_transaction?, который возвращает true при вызове из bar() и false при вызове baz().

В случае, если это имеет значение, я использую базу данных mysql с драгоценным камнем mysql2, и я в порядке с решением, которое работает только для mysql.

4b9b3361

Ответ 1

Вы можете использовать

ActiveRecord::Base.connection.open_transactions

чтобы узнать, выполняется ли ваш метод в транзакции.

ActiveRecord::Base.connection.open_transactions == 0 подразумевает, что ваш метод не выполняется в транзакции. Все, что больше 0, означает, что ваш метод выполняется в транзакции. Например, ActiveRecord::Base.connection.open_transactions > 0

Update:

из документации по рельсам

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