Back

rails - rails中的默认嵌套transaction nested transaction - 结论:BEGIN界限从最外层开始。只有一层

发布时间: 2021-04-01 02:40:00

最精准的答案见:https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

结论:只有一层,就是最外层,里面出错了,外面跟着一起回滚。(我最喜欢)

如果希望外面的transaction不要跟着里面回滚,就参考这个:https://stackoverflow.com/questions/33947190/rails-nested-transactions   

1. 貌似是nested transaction 以最外层的为准

def run 
  Member.transaction do
    Rails.logger.info Member.first
    #raise "lueluelue"


    Rails.logger.info "== before manager transaction"
    Manager.transaction do
      Rails.logger.info Manager.last
      raise "hahaha"
    end 
    Rails.logger.info "after manager transaction"
  end 
  Rails.logger.info "after member transaction"
end

Rails.logger.info "== before run"
run
Rails.logger.info "== after run"

虽然代码很多,但是从logger中可以看出, 只有一个BEGIN的点。 (对应后面的ROLLBACK)

10:34:21 INFO: == before run 
10:34:21 DEBUG:    (0.2ms)  BEGIN 
10:34:21 DEBUG:   Member Load (0.3ms)  SELECT  `members`.* FROM `members`  ORDER BY `members`.`id` ASC LIMIT 1 
10:34:21 INFO: #
10:34:21 INFO: == before manager transaction 
10:34:21 DEBUG:   Manager Load (0.3ms)  SELECT  `managers`.* FROM `managers`  ORDER BY `managers`.`id` DESC LIMIT 1 
10:34:21 INFO: # 
10:34:21 DEBUG:    (0.2ms)  ROLLBACK 

2. 下面是第二个测试的代码(进行了插入测试)

def run2
  SystemVariable.transaction do
    Rails.logger.info "== before key1 created"
    SystemVariable.create name: 'key1', value: 'value1'
    Rails.logger.info "== after key1 created"

    SystemVariable.transaction do
      Rails.logger.info "== before key2 created"
      SystemVariable.create name: 'key2', value: 'value2'
      Rails.logger.info "== after key2 created"
      raise 'destroy key2, will key1 alive?'
    end
  end
end

run2

日志如下,可以看出,跟上面的结论是一样的, 没有任何新记录产生

10:44:48 DEBUG:   Market Load (2.3ms)  SELECT `markets`.* FROM `markets` WHERE `markets`.`visible` = 1 
10:44:49 DEBUG:   Currency Load (1.1ms)  SELECT `currencies`.* FROM `currencies` 
10:44:49 DEBUG:    (0.2ms)  BEGIN 
10:44:49 INFO: == before key1 created 
10:44:49 DEBUG:   SQL (3.4ms)  INSERT INTO `system_variables` (`name`, `value`, `created_at`, `updated_at`) VALUES ('key1', 'value1', '2021-04-01 10:44:49', '2021-04-01 10:44:49') 
10:44:49 INFO: == after key1 created 
10:44:49 INFO: == before key2 created 
10:44:49 DEBUG:   SQL (0.2ms)  INSERT INTO `system_variables` (`name`, `value`, `created_at`, `updated_at`) VALUES ('key2', 'value2', '2021-04-01 10:44:49', '2021-04-01 10:44:49') 
10:44:49 INFO: == after key2 created 
10:44:49 DEBUG:    (5.3ms)  ROLLBACK 

数据库里也没有新的记录。

Back