我有一个相当简单的App Engine Java应用程序,它具有Accounts,Orders和OrderItems - 没有什么疯狂的。简单的Google App Engine数据存储操作耗时过长:导致DeadlineExceededException/DatastoreTimeoutException
就在过去的12个小时里,我已经开始从一些相当直接的代码中抛出异常,这些代码将订单添加到帐户然后保存它们。
我创建了一个简单的测试servlet来复制这个问题,它看起来像这样:
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
String key = req.getParameter("key");
PersistenceManager pm = PMF.get().getPersistenceManager();
Account account = pm.getObjectById(Account.class, KeyFactory.stringToKey(key));
Order order = new Order();
order.setExternalOrderID("ASHLEY-TESTING");
Item item = new Item();
item.setSku("ASHLEY-WIDGET-A");
item.setQuantity(2);
Item item2 = new Item();
item2.setSku("ASHLEY-WIDGET-B");
item2.setQuantity(2);
order.addItem(item);
order.addItem(item2);
account.addOrder(order);
order.setAccount(account);
pm.makePersistent(order);
pm.close();
}
addOrder is implemented as a pretty standard lazy init:
public void addOrder(Order order) {
if (getOrders() == null) {
setOrders(new ArrayList<Order>());
}
getOrders().add(order);
}
The relevant parts of the entities:
@PersistenceCapable
public class Account {
//...
@Persistent(mappedBy="account")
@javax.jdo.annotations.Order(extensions = @Extension(vendorName="datanucleus", key="list-ordering", value="orderDate desc"))
private List<Order> orders;
//...
}
and the Order has an account field:
@Persistent
private Account account;
该代码失败在account.addOrder()
线。如果它直接在浏览器中运行,它将以DeadlineExceededException(30秒之后)失败,如果我通过任务队列排队它,它将在一两分钟后失败,并出现DatastoreTimeoutException。它在此过程中使用卡车装载的CPU时间。
我估计帐户下的订单数少于2000个,每个订单有1-3个OrderItem子。
我的问题是,为什么会突然开始失败,它已经在那里添加了1000个订单。我错过了一些重要的东西吗?我需要添加索引吗?数据存储真的会这么慢吗?我是否在滥用它,如果我没有孩子与这么多孩子的关系 - 也许一组键会是一个更好的方法?