我们假设我们有一个应用程序,允许用户为校内体育创建计划。
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吗?
答案 0 :(得分:0)
未捕获的异常会自动回滚任何受影响的事务。
没有必要提出任何特定类型的异常,因此您可以更准确地提出描述错误的内容。从另一个班级抛出异常似乎是不诚实的。
请注意,根据您的数据库引擎,可能无法在事务中捕获某些类型的操作。例如,MySQL不会对架构进行事务处理。某些引擎甚至可能根本不支持事务,例如MySQL + MyISAM。