[英]Grails efficient batch delete on domain class with cascade delete to child classes
What techniques are people using to efficiently do cascading delete on a large collection of classes? 人们使用什么技术对大量的类进行级联删除?
Suppose I have the following domain 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]
}
Now the number of Members for a given Submission could be very large, say 100,000+, but this is no way limited. 现在,给定提交的成员数量可能非常大,例如100,000+,但这没有限制。 The Events and HashCodes would be say 15 per Member. 每个会员的事件和哈希码为15。
I need to delete some or all of the Members for a given Submission (let's assume all of them for now), but leave the Submission record intact. 我需要删除给定提交的部分或全部成员(现在让我们假设所有成员),但保持提交记录不变。 So I currently do this as follows: 所以我目前这样做如下:
Set<Member> membersToDelete = Member.findAllBySubmissionId( submission.id )
withSessionCleaner(membersToDelete){ member ->
submission.payroll.removeFromMembers( member )
member.delete( failOnError: true )
}
where some generic base service provide the session cleaner as: 其中一些通用基础服务为会话清洁器提供以下功能:
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()
}
}
}
The session cleaner method is required as otherwise Grails retains all objects in the session cache and eventually I get out of memory issues and/or the processing begins to takes a long time towards the end of the collection. 需要使用会话清除器方法,否则Grails会将所有对象保留在会话缓存中,并且最终我会遇到内存不足的问题,并且/或者处理过程在收集结束之前开始花费很长时间。
My main concerns with this approach are: 我对这种方法的主要担心是:
Could I run some SQL queries to achieve what I what: 我可以运行一些SQL查询来实现什么吗:
But now I'm in raw SQL and not really using the Grails classes or relationships. 但是现在我处于原始SQL中,并没有真正使用Grails类或关系。 Are there Grails/GORM commands that would equate to these SQL statements? 是否有Grails / GORM命令等同于这些SQL语句?
Any suggestions? 有什么建议么?
The fastest way is to create FOREIGN KEYS with ON DELETE CASCADE on child objects (hope your DB allows you to do it). 最快的方法是在子对象上使用ON DELETE CASCADE创建FOREIGN KEY(希望您的数据库允许您这样做)。 After that you can safely delete Members by ID, the database will do the rest. 之后,您可以安全地通过ID删除成员,其余的工作将由数据库完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.