如何在Rails中回滚许多事务?

时间:2015-04-15 18:10:33

标签: ruby-on-rails ruby activerecord transactions

我们假设我们有一个应用程序,允许用户为校内体育创建计划。

Alice希望在1月1日下午6点安排A队与B队。

所以,让我们说我们有两个型号。

游戏模型,其中包含 id,日期

一个竞争对手模型持有id,game_id,team_id,home

让我们的A队是team_id 100,B队是team_id 101。

我们的游戏模型将创建一个新条目,

game.id = 1, date = Jan 1 6:00pm.

我们的竞争对手模型将创建2个新条目。

id = assigned, game_id: 1, team_id: 100, home: true
id = assigned, game_id: 1, team_id: 101, home: false

让我们说我将它们保存在一起。如果在第二个参赛者参赛作品的保存中出现错误,我该如何回滚游戏条目和竞争对手参赛作品。

我应该有这样的东西吗?...

Game.transaction do
  Competitor.transaction do
    ...
    team = ...
    opponent_team = ...
    home = home?(team)
    ...
    game = Game.new(date: game_start_date)
    if game.save
      competitor_team = Competitor.new(game_id: game.id, team_id: team.id, home: home)
      if competitor_team.save
        competitor_opponent = Competitor.new(game_id: game.id, team_id: opponent_team.id, home: !home)
        if competitor_opponent.save
          #Do nothing
        else
          raise ActiveRecord::Rollback, competitor_opponent.errors.full_messages
        end
      else
        raise ActiveRecord::Rollback, competitor_team.errors.full_messages
      end
    else
      raise ActiveRecord::Rollback, game.errors.full_messages
    end
  end
end

这些回滚会回滚每次提交的交易吗?如果competitor_opponent.save失败,它会回滚game.save和competitor_team.save吗?

1 个答案:

答案 0 :(得分:0)

未捕获的异常会自动回滚任何受影响的事务。

没有必要提出任何特定类型的异常,因此您可以更准确地提出描述错误的内容。从另一个班级抛出异常似乎是不诚实的。

请注意,根据您的数据库引擎,可能无法在事务中捕获某些类型的操作。例如,MySQL不会对架构进行事务处理。某些引擎甚至可能根本不支持事务,例如MySQL + MyISAM。