数据存储 - 单个实体组中的资源争用 -

时间:2012-07-31 16:42:33

标签: google-app-engine

关于数据存储,我对以下内容感到迷茫:

  • 建议对数据进行非规范化,因为数据存储区不支持连接查询。这意味着相同的信息将被复制到多个实体中

  • 非规范化意味着无论何时必须更新 数据,必须在不同的实体中更新

  • 但单个实体组的写入速度限制为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) ;        
    }              
}

2 个答案:

答案 0 :(得分:3)

这种情况正在发生,因为在短时间内发生了多次更新同一实体组的请求,而不是因为您正在同时更新同一实体组中的多个实体。

由于您没有显示您的代码,我可以假设发生了两件事之一:

  1. 您在上面描述的方法实际上并未使用事务,并且您正在运行具有同一实体组的许多实体的put_multi()。 (如果我不得不猜测,那就是这个。)
  2. 您有一个高流量网站,同时还有许多其他更新同时发生。

答案 1 :(得分:1)

以防某些人遇到同样的问题。

问题出现在party.update(partyDTO)中,在某些特定情况下,我正在启动另一项交易。

我今天学到的是:

- &GT;在交易中,您可以包含多个看跌期权甚至超过1个实体/秒

- &GT;但是,您应该注意不要在事务中启动另一个事务