【问题标题】:rails transaction rollback results in discontinuous idrails事务回滚导致id不连续
【发布时间】:2016-07-26 05:32:52
【问题描述】:

我正在使用 postgresql 和 rails 4.2 进行应用程序开发。

问题来了:

在创建用户模型时,我需要同时创建与用户模型关联的另外两个模型:配置文件模型和 user_behavior 模型。为了保持记录的一致性,事务是这样使用的:

begin
  @new_user = User.new
  @new_user.transaction do
    @new_user.update_attributes!(users_params)
    @new_user.profile = Profile.create!(profiles_params)
    @new_user.user_behavior = UserBehavior.create!
  end
rescue ActiveRecord::RecordInvalid => exception
  render_response_msg(4003, { message: exception.message })
rescue ArgumentError => exception
  render_response_msg(4003, { message: "invalid parameters" })
end
@new_user

用户模型和配置文件模型都有一些验证

问题 1. 我使用实例变量 @new_user 将新创建的用户记录带出事务范围,我不确定这是执行此操作的通用方法,还有其他想法吗?

问题2.当用户参数正确时,通过并创建用户记录,则配置文件参数无效,使整个事务回滚。然后我发现用户模型的id(rails中模型的基本自动增量id)是不连续的。例如,如果由于配置文件参数而失败两次,那么成功事务将创建 id = 3 的模型。我该如何解决这个问题?

【问题讨论】:

  • 为什么id 值的差距是个问题?它们将是独一无二的,这就是真正保证的一切。

标签: ruby-on-rails postgresql transactions rollback


【解决方案1】:

[无法编辑对问题 1 的响应,因为无法返回局部变量,正如我在评论中指出的那样,我在原始帖子中错过了这一点]

针对问题1: 我认为本文提供的描述http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html 会有帮助的。因此,我会做如下事情:

User.transaction do
    new_user = User.new(user_params)
    new_user.profile = Profile.create!(profile_params)
    new_user.behavior = UserBehavior.create!
    new_user.save!
end

针对问题 2:正如mu is too short 指出的那样,这应该没关系,但是 postgresql 为数据库中的每个表使用一个序列表,通常命名为[YOUR_TABLE_NAME]_id_seq 你将不得不更改 last_value 列的值该表是为了调整 id 序列,但是一个错误肯定会在保持唯一性方面造成很多问题,我当然建议不要玩弄它。

【讨论】:

  • 注意我需要在这个方法中返回新创建的用户记录,如果new_user被用作局部变量,我无法检索出事务范围之外的实体。
  • 哦,是的!我很抱歉我完全错过了。我将编辑我的答案
  • 另外,我认为如果您在事务之前将变量初始化为new_user,那么您可以在没有实例变量的情况下实现您想要实现的目标,它应该仍然可以在begin 块中访问。你可以在rescue ActiveRecord::RecordInvalid => exception 之前添加一个return new_user,如果你不想在那个时候返回并且需要在begin块之外访问new_user,那么在begin块开始之前初始化new_user
  • 好的,谢谢您的热心回复,Ruby 关闭,我知道了。我没有解释清楚是我的错。我想将实例变量返回给视图,所以这里我使用实例变量。实际上我想问的是,作为我的代码,在事务之外初始化一个模型,然后在范围内更新它的属性。是否有更常见或更优雅的方式来完成此操作。再次感谢您。
  • 哦,现在我明白了。好吧,如果它必须返回到视图中,您将需要一个实例变量。我不知道另一种方式可以实现你想要的。谢谢你的澄清。
猜你喜欢
  • 2021-05-14
  • 2013-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-31
  • 2010-10-02
相关资源
最近更新 更多