2

良い一日!

GWT 2.4 で並行性節約を実装しようとしました。ユーザーケースがあります:

  1. ユーザー John と Jim が 1 つのエンティティを開いて編集する
  2. John は変更を保存します。大丈夫。
  3. 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!.

何が起こったのかわかりません。ジムが変更を上書きすると、クライアント層ではすべてが正しくなりますが、サーバー層は前のユーザーによって保存されたデータで機能します。

この状況で変更を正しく上書きする方法を知っている人はいますか?

4

1 に答える 1

1

上書き保存する場合、最初に送信したエンティティと同じエンティティを編集し、その後凍結してから切り離しますRequestContext。そのため、エンティティを新しく作成された に渡すと、エンティティはRequestContext暗黙的にs になり、変更が適用されないため、 dedit()のときに空の diff がサーバーに送信されます。fire()したがって、サーバーは、1) データベースからエンティティをロードする、2) 差分を適用する (つまり、差分が空なので何もしない)、3) エンティティを保存するように求められます。最後に持続しました。

理想的にedit()は、最初のリクエストと同じエンティティに同じ変更を適用して、まったく同じ差分をサーバーに送信する必要があります。残念ながら、これを行う簡単な方法はありません (編集したデータを誰がプロキシに入れるかによって異なります)。

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 を割り当てる)ことで、確認せずに保存することが重要です。

于 2012-10-03T14:09:13.560 に答える