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

use*_*729 30 ruby mysql activerecord transactions ruby-on-rails

ActiveRecord::Base.transaction do
  Foo.new.bar
end
Foo.new.baz
Run Code Online (Sandbox Code Playgroud)

我可以从内部决定程序bar()baz()方法,如果交易已经发生?寻找的东西可能看起来像 ActiveRecord::Base.within_transaction?,这将返回true从调用时bar()false时呼吁baz().

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

ush*_*sha 46

您可以使用

ActiveRecord::Base.connection.open_transactions
Run Code Online (Sandbox Code Playgroud)

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

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 
Run Code Online (Sandbox Code Playgroud)


Eug*_*ica 18

在 Rails 6.0 中你可以使用:

ActiveRecord::Base.connection.transaction_open?
Run Code Online (Sandbox Code Playgroud)