【问题标题】:Grails efficient batch delete on domain class with cascade delete to child classesGrails在域类上高效批量删除,级联删除到子类
【发布时间】:2013-03-07 16:18:42
【问题描述】:

人们使用什么技术有效地对大量类进行级联删除?

假设我有以下域类:

class Submission {
   static hasMany = [members: Member]
}

class Member {
   static belongsTo = [submission: Submission]
   static hasMany = [events: Event, hashCodes: HashCode]
}

class Event {
   static belongsTo = [member: Member]
}

class HashCode {
   static belongsTo = [member: Member]
}

现在,给定提交的成员数量可能非常大,例如 100,000+,但这绝不是有限的。事件和哈希码是每个成员 15 个。

我需要删除给定提交的部分或全部成员(我们现在假设所有成员),但保留提交记录不变。所以我目前这样做如下:

Set<Member> membersToDelete = Member.findAllBySubmissionId( submission.id )
withSessionCleaner(membersToDelete){ member ->
   submission.payroll.removeFromMembers( member )
   member.delete( failOnError: true )
}

其中一些通用基础服务提供会话清理器:

SessionFactory sessionFactory
def propertyInstanceMap = org.codehaus.groovy.grails.plugins.DomainClassGrailsPlugin.PROPERTY_INSTANCE_MAP
private static final int DEFAULT_SESSION_CLEANER_CHECKPOINT = 100
def withSessionCleaner(def items, Closure c)
{
    items.eachWithIndex { obj, index ->
       c(obj)
       if (++index % DEFAULT_SESSION_CLEANER_CHECKPOINT == 0) {
           def session = sessionFactory.currentSession
           session.flush()
           session.clear()
           propertyInstanceMap.get().clear()
        }
    }
}

会话清理方法是必需的,否则 Grails 会将所有对象保留在会话缓存中,最终我会出现内存不足问题和/或处理开始需要很长时间才能接近集合结束。

我对这种方法的主要担忧是:

  1. Grails 为 Member/Event/HashCode 类从数据库读取或加载到内存中的是什么?我听说过延迟加载,但不知道如何在这 3 个类上检查或配置它。
  2. 单独处理每个成员似乎对于级联删除工作是必要的,但对于我想要实现的目标来说似乎可能很昂贵。

我可以运行一些 SQL 查询来实现我的目标吗:

  1. delete from Event where member_id in (select id from Member where submit_id = ?)
  2. 从 HashCode where member_id in 中删除(select id from Member where submit_id = ?)
  3. delete from Member where submit_id = ?

但现在我使用的是原始 SQL,并没有真正使用 Grails 类或关系。是否存在等同于这些 SQL 语句的 Grails/GORM 命令?

有什么建议吗?

【问题讨论】:

    标签: mysql grails grails-orm


    【解决方案1】:

    最快的方法是在子对象上使用 ON DELETE CASCADE 创建 FOREIGN KEYS(希望您的数据库允许您这样做)。之后,您可以按 ID 安全地删除成员,数据库将完成剩下的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 2021-08-19
      • 2018-08-28
      • 1970-01-01
      • 2014-05-08
      相关资源
      最近更新 更多