如何判断是否已经在ruby on rails中的数据库事务中?

时间:2013-11-20 17:18:58

标签: mysql ruby-on-rails ruby activerecord transactions

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

我是否可以在bar()baz()方法中以编程方式确定交易是否已经发生?寻找可能看起来像的东西 ActiveRecord::Base.within_transaction?,当truebar()被调用false时会返回baz()

如果它是相关的,我正在使用带有mysql2 gem的mysql数据库,并且可以使用仅适用于mysql的解决方案。

2 个答案:

答案 0 :(得分:40)

您可以使用

ActiveRecord::Base.connection.open_transactions

查看您的方法是否在事务中执行。

ActiveRecord::Base.connection.open_transactions == 0表示您的方法未在事务中执行。大于0的任何内容都意味着您的方法在事务中执行。例如ActiveRecord::Base.connection.open_transactions > 0

更新

来自rails文档

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

因此,即使您处于嵌套事务中,打开事务的数量也将为1。

这是我在我的控制台中得到的

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 

答案 1 :(得分:2)

在 Rails 6.0 中你可以使用:

ActiveRecord::Base.connection.transaction_open?