1

我正在尝试清除一个集合并同时更新它。它有孩子,在集合中查找当前项目并异步删除它们将为我节省大量时间。

步骤 1. 找到集合中的所有项目。第 2 步。一旦我知道这些项目是什么,就创建一个流程来删除它们。

def memberRedbackCriteria = MemberRedback.createCriteria()
    // #1 Find all the items in the collection.
    def oldList = memberRedbackCriteria.list { fetchMode("memberCategories", FetchMode.EAGER) }
    // #2 Delete them.
    Promise deleteOld = task {
        oldList.each { MemberRedback rbMember ->
              rbMember.memberCategories.clear()
              rbMember.delete()
         }
 }

错误消息是:非法尝试将集合与两个打开的会话相关联

我猜是因为我找到了项目,然后分叉,这会创建一个新会话,以便在分叉之前构建集合,并使用新会话来删除项目。

我需要收集当前线程中的项目,否则我不确定状态会是什么。

4

2 回答 2

2

请注意,对所有删除使用一个异步任务实际上是在单个线程中连续运行所有删除操作。假设您的数据库可以处理多个连接和一个表的并发修改,您可以使用 PromiseList 并行化删除,如下所示(注意下面的未经测试的代码)。

def deletePromises = new PromiseList()
redbackIds.each { Long rbId ->
    deletePromises << MemberRedback.async.task {
        withTransaction {
            def memberRedbackCriteria = createCriteria()
            MemberRedback memberRedback = memberRedbackCriteria.get {
                idEq(rbId)
                fetchMode("memberCategories", FetchMode.EAGER) }
            memberRedback.memberCategories.clear()
            memberRedback.delete()
        }
    }
}
deletePromises.onComplete { List results ->
    // do something with the results, if you want
}
deletePromises.onError { Throwable err ->
    // do something with the error
}
于 2013-11-29T16:32:18.563 回答
0

找到了解决方案。将 id 放入列表中,并将它们作为异步闭包的一部分收集。

另请注意,您不能按照http://jira.grails.org/browse/GRAILS-1967重用标准

// #1 find the ids
def redbackIds = MemberRedback.executeQuery(
                'select mr.id from MemberRedback mr',[])

// #2 Delete them.
Promise deleteOld = task {
       redbackIds.each { Long rbId ->
            def memberRedbackCriteria = MemberRedback.createCriteria()
            MemberRedback memberRedback = memberRedbackCriteria.get {
                idEq(rbId)
                fetchMode("memberCategories", FetchMode.EAGER) }
            memberRedback.memberCategories.clear()
            memberRedback.delete()
       }
 }
 deleteOld.onError { Throwable err ->
      println "deleteAllRedbackMembers An error occured ${err.message}"
 }
于 2013-10-31T03:40:19.333 回答