人们使用什么技术来有效地对大量类进行级联删除?
假设我有以下域类:
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 会将所有对象保留在会话缓存中,最终我会出现内存不足问题和/或处理开始需要很长时间才能接近集合结束。
我对这种方法的主要担忧是:
- 什么是 Grails 从数据库读取或加载到 Member/Event/HashCode 类的内存中?我听说过延迟加载,但不确定如何在这 3 个类上检查或配置它。
- 单独处理每个成员似乎对于级联删除工作是必要的,但对于我想要实现的目标来说似乎可能很昂贵。
我可以运行一些 SQL 查询来实现我的目标吗:
- 从其中 member_id 的 Event 中删除(从 Member where submit_id = 中选择 id)
- 从 HashCode where member_id in (select id from Member where submit_id = ?) 中删除
- 从成员中删除 submit_id = ?
但现在我使用的是原始 SQL,并没有真正使用 Grails 类或关系。是否存在等同于这些 SQL 语句的 Grails/GORM 命令?
有什么建议么?