2013-10-31 1 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() 
     } 
} 

오류 메시지는 다음과 같습니다 불법 시도가 두 개의 열린 세션

과 모음을 연결하는

난 후, 포크 항목을 찾을 수 있기 때문에 컬렉션이 구축 될 수 있도록이 과정이 새로운 세션을 생성하는 추측하고있다 forking 전에 새 세션을 사용하여 항목을 삭제합니다.

현재 스레드에서 항목을 수집해야합니다. 그렇지 않으면 상태가 무엇인지 알 수 없습니다.

답변

0

해결책을 찾았습니다. 목록에 ID를 넣고 비동기 폐쇄의 일부로 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

quad imac에 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