1

私はデータストアに関して次のことに迷っています:

  • データストアは結合クエリをサポートしていないため、データを非正規化することをお勧めします。これは、同じ情報が複数のエンティティにコピーされることを意味します

  • 非正規化とは、データを更新する必要がある場合は常に、別のエンティティで更新する必要があることを意味します

  • ただし、単一のエンティティグループには1書き込み/秒の制限があります。

したがって、私が抱えている問題は次のとおりです。

  • レコードを更新するために、トランザクションを開いてから

  • 必要なすべてのエンティティを更新します。更新されるエンティティは同じエンティティグループ内にありますが、異なる種類に関連しています

  • 「リソース競合」例外が発生します

==>したがって、非正規化されたデータを更新する唯一の方法は、トランザクションの外部にあるようです。しかし、これを行うことは、一部のエンティティが更新される可能性があるのに対し、他のエンティティは更新されないため、非常に悪いことです。

この問題を抱えているのは私だけですか?どのようにそれを解決しましたか?

ありがとう、

ヒューグ

(簡略化されたバージョンの)コードは次のとおりです。

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) ;        
    }              
}
4

2 に答える 2

3

これは、同じエンティティグループ内の多数のエンティティを一度に更新するためではなく、同じエンティティグループを更新するための複数の要求が短期間に発生するために発生します。

コードを表示していないので、次の2つのいずれかが発生していると推測できます。

  1. 上記で説明した方法は、実際にはトランザクションを使用しておらずput_multi()、同じエンティティグループの多くのエンティティで実行しています。(私が推測しなければならなかったなら、それはこれでしょう。)
  2. トラフィックの多いサイトがあり、他の多くの更新が同時に発生しています。
于 2012-07-31T17:50:26.480 に答える
1

誰かが同じ問題に遭遇した場合に備えて。

問題はparty.update(partyDTO)にあり、特定の条件下で別のトランザクションを開始していました。

私が今日学んだことはそれです:

->トランザクション内では、1エンティティ/秒を超えても複数のプットを含めることができます

->ただし、トランザクション内で別のトランザクションを開始しないように注意する必要があります

于 2012-07-31T19:45:05.410 に答える