2013-10-31 29 views
1

我想清除一个集合并同时更新它。它有孩子,找到收藏中的当前项目并异步删除它们会为我节省很多时间。Grails,Promise API和两个打开的会话

第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() 
     } 
} 

的错误信息是:非法尝试集合有两个打开的会话

关联

我猜想那是因为我找到的项目,然后叉,这将创建一个新的会话,以便收集建分叉之前和新会话用于删除项目。

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

回答

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}" 
} 
+0

这和做同步不一样吗?我的意思是你可以运行条件来提取协会热切,然后删除它们? – dmahapatro

+0

似乎为四十万像素上的100k记录节省10分钟。 – Interlated

+0

删除时间比生成时间长。删除35分钟为一个线程。创建的项目包括从远程服务器下载,计算增量和节省30k - 花了25分钟。 – Interlated

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 
} 
+0

生成新版本时删除东西的算法工作正常。托管公司正在嘲笑我使用基于光标的删除而不是从删除。我还没有计时或查看异步查询解决方案。看看多余的分岔产生了多少额外开销会很有趣。 – Interlated