2012-10-03 2 views
2

좋은 하루!GWT의 동시성 절약

GWT 2.4에서 동시성 절약을 구현하려고했습니다. 사용자의 경우가 있습니다 :

  1. 사용자 존과 짐은 요한이 자신의 변경 사항을 저장
  2. 을 편집 한 개체를 엽니 다. 다 괜찮아.
  3. 짐 (Jim)은 변경 사항을 저장합니다. 시스템 덮어 쓰기에 대한 질문

    a. Jim은 덮어 쓰기를 원하지 않습니다. 시스템은 페이지의 엔티티를 새로 고칩니다.

    b. 그렇지 않으면 Jim이 변경 사항을 저장하려고하면 변경 사항을 유지해야하며 John의 변경 사항이 삭제됩니다. (변경 내역에만 남음)

그래서 나는 3.b에 문제가 있습니다.

public void save(MyEntityProxy entity){ 
    MyRequest rContext = (MyRequest) driver.flush(); 
    MyProxy myEntity = (MyProxy) rContext.edit(entity); 
    entitySave(rContext, (MyProxy) myEntity, false); 
} 

private void entitySave(MyRequest rContext, final MyProxy myEntity, boolean overwrite){ 
    GWT.log("SAVE ENTITY WITH NAME = " + myEntity.getName()); 
    rContext.persist(myEntity, entityVersion, overwrite) 
    .fire(new Receiver<MyProxy>() { 
     @Override 
     public void onSuccess(MyProxy response) { 
      goToModel(); 
     } 
     @Override 
     public void onFailure(ServerFailure error) { 
      if(isConcurency(error)){ 
       entitySave((MyRequest)getNewRequestContext(), myEntity,true); 
      } 
     } 
    }); 
} 

/*This is a method from MyService for persisting*/ 
public MyProxy persist(MyProxy entity, Long version, boolean overwrite) { 
    LOG.info("PERSISTS ENTITY NAME=" + entity.getName()); 
    if(!overwrite && !checkVersionChanged(entity, version)){  
     System.out.println("RAISE CHANGED_BY_OTHER EXCEPTION"); 
     throw new RuntimeException(CHANGED_BY_OTHER.name());    
    } 
    entity = getEntityManager().merge(entity); 
    getEntityManager().flush(); 
    return entity; 
} 

isConcurrency은 동시성 문제를 확인하기위한 방법이며 사용자가 대화 상자에서 지점을 선택 "덮어 쓰기"경우에 true를 돌려줍니다.

GWT 로그 :

SAVE ENTITY WITH NAME = John //There is John changed name of entity 
SAVE ENTITY WITH NAME = Jim //There is John changed name of entity 
SAVE ENTITY WITH NAME = Jim //There is John overwrites entity 

서버 로그 : 무슨 일이 있었는지 이해가 안

[INFO] PERSISTS ENTITY NAME=Jim //There is John changed name of entity 
[INFO] SAVE ENTITY NAME=Jim  //Persisting of John's changes. Here John finished his work 
[INFO] PERSISTS ENTITY NAME=John //There is Jim changed name of entity 
[INFO] RAISE CHANGED_BY_OTHER EXCEPTION //Exception raises and dialog shows for Jim 
[INFO] PERSISTS ENTITY NAME=John //Second iteration of saving. Look at the name!. 

. Jim이 변경 내용을 덮어 쓰면 클라이언트 계층에서 모두 올바르지 만 서버 계층은 이전 사용자가 저장 한 데이터로 작동합니다.

이 상황에서 어떻게 변경 사항을 올바르게 덮어 쓸 수 있습니까? 당신이 덮어 저장하면 당신이 주변에 처음 전송 한 후 냉동RequestContext에서를 분리 한 후 을 된로

답변

1

, 당신은 동일한 개체를 편집 할 수 있습니다. 따라서 새로 생성 된 RequestContext에 엔티티를 전달하면 암시 적으로 edit()입니다. 적용된 변경 사항이 없으므로 fire() d가되면 서버에 비어있는 diff를 보냅니다. 따라서 서버는 1) 데이터베이스에서 엔티티를로드하고, 2) diff를 적용하고 (즉, diff가 비어 있으므로 아무 것도하지 않습니다.) 3) 엔티티를 저장합니다.이 시점에서 엔티티를 저장합니다. 마지막으로 지속되었습니다.

이상적으로는 첫 번째 요청과 동일한 엔티티 인 edit()을 입력하고 동일한 변경 사항을 다시 적용하여 정확히 동일한 diff를 서버에 보낼 수 있습니다. 유감 스럽지만 쉽게 할 수있는 방법이 없습니다. (편집 한 데이터를 누가 프록시에 저장했는지에 따라 다릅니다.)

http://code.google.com/p/google-web-toolkit/issues/detail?id=5794http://code.google.com/p/google-web-toolkit/issues/detail?id=6046

분명하지만, RequestFactory이 사용 사례에 맞게 조정되지를 참조하십시오,이 응용 프로그램이 할 수있는 방법을 제공하여,을 요청하지 않고 저장 등에 대한 있어이 변경 (예는 로그온 취소 서버에 할당하고 ID를 할당).

+0

빠른 답변 감사합니다. 날 구해 줬어. – Serg