繁体   English   中英

使用级联删除子类对域类进行Grails高效的批量删除

[英]Grails efficient batch delete on domain class with cascade delete to child classes

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

假设我具有以下域类:

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. 对于Member / Event / HashCode类,Grails从数据库读取或加载到内存中的是什么? 我听说过延迟加载,但是不确定如何在这3个类上进行检查或配置。
  2. 单独处理每个成员似乎是级联删除工作所必需的,但对于我要实现的目标来说似乎很昂贵。

我可以运行一些SQL查询来实现什么吗:

  1. 从其中member_id所在的事件中删除(从Member中的submit_id =吗?
  2. 从HashCode中删除member_id所在的位置(从Member中选择id,其中submitt_id =吗?)
  3. 从会员中删除,其中commit_id =?

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

有什么建议么?

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM