我已经使用appstats多次验证了这一点。当以下代码未包装在事务中时,JDO执行两次数据存储读取和一次写入,3次RPC,成本为240.不仅是第一次,每次,即使每次都访问相同的记录因此应该从缓存中拉出来。但是,当我在上面的事务中包装代码时,代码生成4个RPC:begin transaction,get,put和commit - 这些只有Get被记为数据存储读取,所以总成本是70。
如果它从缓存中提取它,为什么它只会为读取收费?它似乎会为写入而不是读取而收费。对于非事务性缓存读取,app引擎可能会为数据存储区读取计算相同的金额吗?为什么?
这是代码WITH transaction:
PersistenceManager pm = PMF.getManager();
Transaction tx = pm.currentTransaction();
String responsetext = "";
try {
tx.begin();
Key userkey = obtainUserKeyFromCookie();
User u = pm.getObjectById(User.class, userkey);
Key mapkey = obtainMapKeyFromQueryString();
// this is NOT a java.util.Map, just FYI
Map currentmap = pm.getObjectById(Map.class, mapkey);
Text mapData = currentmap.getMapData(); // mapData is JSON stored in the entity
Text newMapData = parseModifyAndReturn(mapData); // transform the map
currentmap.setMapData(newMapData); // mutate the Map object
tx.commit();
responsetext = "OK";
} catch (JDOCanRetryException jdoe) {
// log jdoe
responsetext = "RETRY";
} catch (Exception e) {
// log e
responsetext = "ERROR";
} finally {
if (tx.isActive()) {
tx.rollback();
}
pm.close();
}
resp.getWriter().println(responsetext);
这是没有交易的代码:
PersistenceManager pm = PMF.getManager();
String responsetext = "";
try {
Key userkey = obtainUserKeyFromCookie();
User u = pm.getObjectById(User.class, userkey);
Key mapkey = obtainMapKeyFromQueryString();
// this is NOT a java.util.Map, just FYI
Map currentmap = pm.getObjectById(Map.class, mapkey);
Text mapData = currentmap.getMapData(); // mapData is JSON stored in the entity
Text newMapData = parseModifyAndReturn(mapData); // transform the map
currentmap.setMapData(newMapData); // mutate the Map object
responsetext = "OK";
} catch (Exception e) {
// log e
responsetext = "ERROR";
} finally {
pm.close();
}
resp.getWriter().println(responsetext);
答案 0 :(得分:2)
通过事务,PersistenceManager
可以知道缓存在整个代码处理过程中是有效的。如果没有事务,它就不能(它不知道是否有其他操作在其后面进行并且更改了事物),因此必须根据数据库表验证缓存的内容。每次检查时,都需要创建一个事务来执行此操作;这是数据库接口本身的一个特性,其中任何不在事务中的操作(具有一些特定于数据库的异常)将自动添加事务。
在您的情况下,您应该有一个事务,因为您希望在进行处理时拥有一致的数据库视图。如果没有这个,mapData
可能会被另一个操作修改,而你正在处理它,那些修改将会无声地丢失。那会很糟糕。 (好吧,可能。)交易是治愈方法。
(您还应该考虑使用AOP来管理事务包装;这比每次自己编写所有事务管理代码要容易得多.OTOH,它可以为部署增加很多复杂性,直到您把事情做好,所以我可以理解不遵循这条建议......)