【问题标题】:How to destroy millions of dependent objects in Rails如何在 Rails 中销毁数百万个依赖对象
【发布时间】:2018-01-26 08:58:53
【问题描述】:

在 Rails 中,我一直使用 dependent: :destroy 来删除依赖对象。

但是在以下场景中它不能正常工作,因为订阅和通知非常大,必须销毁数百万个对象。

Users --> Projects  --> Subscriptions
                   \
                    --> Notifications

一些问题是:

  • 删除速度非常慢,可能需要几个小时(我可以使用后台作业)
  • 我不能在大表上使用dependent: :delete_all,因为它会长时间阻塞数据库
  • user.destroy 将所有删除都包装在一个事务中(我认为这对于同时必须为其他查询提供服务的数据库来说并不好)

Rails 处理包含数百万条记录的大型销毁的方法是什么?是否有任何宝石可以帮助和以更好的方式处理dependent: :destroy(例如在交易之外)?在这种情况下,您会建议什么方法?

【问题讨论】:

  • 不知道有没有宝石。我使用后台作业并向用户和项目添加状态 (BEING_DELETED) 来处理删除发生时的情况。
  • 我会删除 dependent: :destroy 并通过 after_destroy 回调触发清理工作。除非在同一事务中需要删除关键任务数据,否则就可以了。我不认为有处理这种情况的“rails 方式”。
  • @phoet 您的方法的唯一问题是,在您尝试访问父对象的同时可能会发生一些错误(例如,notification.project 可能会导致一些错误,因为在您的应用程序中您期望项目出席)
  • 这是正确的。这都是关于权衡,你不能同时拥有一致性和速度(这就是最终一致性的全部内容)

标签: ruby-on-rails rails-activerecord


【解决方案1】:

从 Rails 6.1 开始,可以使用 dependent: :destroy_async 在后台销毁关联

 has_many :subscriptions, dependent: :destroy_async

刚刚发布此内容以供将来参考

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 2013-01-22
    • 1970-01-01
    • 2017-06-29
    • 2012-02-06
    相关资源
    最近更新 更多