2012-07-31 3 views
1

나는 다음에 관한 데이터 저장소에 잃어버린하고는 :데이터 저장소 - 단일 엔티티 그룹의 자원 경합 -

  • 데이터 저장소 쿼리에 가입 지원하지 않는 데이터를 비정규 화하는 것이 좋습니다. 이 같은 정보를 여러 기관에서 복사

  • 비정규 당신이 데이터를 업데이트 할 때마다, 그것은 다른 개체

  • 업데이트되어야 함을 의미하지만 1 개 쓰기의 한계/초에 존재하는 것을 의미 단일 엔티티 그룹 레코드를 업데이트하기 위해

    • , 내가 트랜잭션을 다음

    • 업데이트에 필요한 모든 요소를 ​​엽니 다

    내가 가진 문제는 다음 그러므로이다. 업데이트 할 수있는 개체는 같은 개체 그룹 내에서하지만 다른 종류의

  • 나는 "리소스 경합을"점점 오전 예외 관련

유일한 방법은 업데이트 할 것을 그러므로 보인다>== 비정규 화 된 데이터가 트랜잭션 외부에 있습니다. 그러나 일부 엔티티가 업데이트 될 수있는 반면 다른 엔티티는 업데이트 될 수 없으므로이를 수행하는 것은 매우 나쁩니다.

나는이 문제가있는 유일한 사람입니까? 어떻게 그걸 해결 했니?

감사합니다,

Hugues

다음과 같이 코드 (의 단순화 된 버전)입니다 : 여러 요청이 동일한 개체 그룹을 업데이트 할 수 있기 때문에

Objectify ofy=ObjectifyService.beginTransaction(); 

try { 
    Key<Party> partyKey=new Key<Party>(realEstateKey, Party.class, partyDTO.getId()); 

    //-------------------------------------------------------------------------- 
    //-- 1 - We update the party 
    //-------------------------------------------------------------------------- 
    Party party=ofy.get(partyKey); 
    party.update(partyDTO); 

//--------------------------------------------------------------------------------------------- 
//-- 2 - We update the kinds which have Party as embedded field, all in the same entity group 
//--------------------------------------------------------------------------------------------- 

    //2.1 Invoices 

    Query<Invoice> q1=ofy.query(Invoice.class).ancestor(realEstateKey).filter("partyKey", partyKey); 
    for (Invoice invoice: q1) { 
     invoice.setParty(party); 
    ofy.put(invoice); 
    } 
    //2.2Payments 
    Query<Payment> q2=ofy.query(Payment.class).ancestor(realEstateKey).filter("partyKey", partyKey); 
    for (Payment payment: q2) { 
     payment.setParty(payment); 
    ofy.put(payment); 
    } 
} 

    ofy.getTxn().commit(); 
    return (RPCResults.SUCCESS); 
} 

catch (Exception e) {  
     final Logger log = Logger.getLogger(InternalServiceImpl.class.getName());  
     log.severe("Problem while updating party : " + e.getLocalizedMessage()); 
     return (RPCResults.FAILURE) ;  
} 

finally { 
    if (ofy.getTxn().isActive()) { 
     ofy.getTxn().rollback(); 
    partyDTO.setCreationResult(RPCResults.FAILURE); 
    return (RPCResults.FAILURE) ;   
    }    
} 
+0

오류 코드와 게시 추적을 게시 하시겠습니까? – mjibson

+0

@mjibson 스택 추적 : com.plugimmo.web.server.internal.service.InternalServiceImpl requestUpdateLease : 임대를 갱신하는 중 문제점 : 이러한 데이터 스토어 엔티티에서 너무 많은 경합이 발생합니다. 다시 시도하십시오. – Hugues

+0

코드를 게시하면 더 많은 도움을받을 수 있습니다. – mjibson

답변

1

누군가가 동일한 문제에 봉착하는 경우.

문제점은 특정 조건 하에서 다른 트랜잭션을 시작한 party.update (partyDTO)에있었습니다.

는 내가 오늘 배운 즉 :

-> 트랜잭션 내부, 당신도 초/1 개 기업에

받고 여러 박았을 포함 할 수 있습니다 -> 그러나, 당신이해야 치료를 거래 내에서 다른 거래를 시작하지 마십시오.

3

이런 일이 발생된다 짧은 엔티티 그룹의 많은 엔티티를 한 번에 업데이트하기 때문에가 아닙니다.

  1. 실제로 트랜잭션을 사용하지 않는 위의 설명 방법과 같은 많은 단체와 put_multi()을 실행 : 당신은 당신의 코드를 표시하지 않았으므로

    , 나는 두 가지 중 하나가 일어나고 가정 할 수있다 엔티티 그룹. (내가 추측해야한다면, 이것이 될 것입니다.)

  2. 트래픽이 많은 사이트가 있으며 동시에 많은 업데이트가 동시에 발생합니다.
+0

죄송합니다. 내 코드를 추가하는 것을 잊었습니다. 아래 간단한 버전을 찾으실 수 있습니다 : – Hugues

+0

도와 주셔서 감사합니다. 대단히 감사합니다, Hugues – Hugues

관련 문제