今天我第一次使用GWT和JDO。我在本地调试模式下使用Eclipse运行它。
我做了以下事情:
public Collection<MyObject> add(MyObject o) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
pm.makePersistent(o);
Query query = pm.newQuery(MyObject.class);// fetch all objects incl. o. But o only sometimes comes...
List<MyObject> rs = (List<MyObject>) query.execute();
ArrayList<MyObject> list= new ArrayList<MyObject>();
for (MyObject r : rs) {
list.add(r);
}
return list;
} finally {
pm.close();
}
}
我已在<property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" />
中设置了jdoconfig.xml
。我是否必须在配置中设置其他一些事务?有人找到了工作jdoconfig.xml
吗?或者是其他地方的问题?中间有一些缓存?
编辑:我尝试过的事情:
PersistenceManager
,但多次调用PMF.get().getPersistenceManager()
PersistenceManager
flush
和checkConsistency
jdoconfig:
<persistence-manager-factory name="transactions-optional">
<property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" />
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
我必须在这里遗漏一些东西,因为所有方法都失败了......
EDIT2:当我将作业拆分为两个事务时,日志表示写入事务已完成,然后读取事务开始。但它没有找到刚才持久的对象。它总是说Level 1 Cache of type "weak" initialised
。周是坏还是好?
大约30%的请求出错了......我可能会遇到一些懒惰的查询加载问题吗?
答案 0 :(得分:2)
调用makePersistent()
方法不会写入数据存储区;关闭PersistenceManager或提交更改。由于在运行查询时尚未执行此操作,因此您将从数据存储区获取所有对象,但尚未包含刚刚调用makePersistent的对象。
在这里阅读对象状态: http://db.apache.org/jdo/state_transition.html
有两种解决方法,你可以把它放在一个事务中,因为提交写入数据存储区(记住事务中的GAE 5事务/实体类型限制)并在运行查询之前提交; 使用事务的示例...
public Collection<MyObject> add(MyObject o) {
PersistenceManager pm = PMF.get().getPersistenceManager();
ArrayList<MyObject> list = null;
try {
Transaction tx=pm.currentTransaction();
try {
tx.begin();
pm.makePersistent(o);
tx.commit();
} finally {
if (tx.isActive()) {
tx.rollback();
}
}
Query query = pm.newQuery(MyObject.class);
List<MyObject> rs = (List<MyObject>) query.execute();
ArrayList<MyObject> list = new ArrayList<MyObject>();
for (MyObject r : rs) {
list.add(r);
}
} finally {
pm.close();
}
return list;
}
或者你可以在o上调用makePersistent之后关闭持久性管理器,然后打开另一个来运行你的查询。
// Note that this only works assuming the makePersistent call is successful
public Collection<MyObject> add(MyObject o) {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
pm.makePersistent(o);
} finally {
pm.close();
}
pm = PMF.get().getPersistenceManager();
ArrayList<MyObject> list = null;
try {
Query query = pm.newQuery(MyObject.class);
List<MyObject> rs = (List<MyObject>) query.execute();
list= new ArrayList<MyObject>();
for (MyObject r : rs) {
list.add(r);
}
} finally {
pm.close();
}
return list;
}
注意:我原先说过你可以在返回之前将o
添加到结果列表中;但是,如果将o
写入数据存储区时出现问题,那么这不是一件明智的事情;然后返回的列表不会反映数据存储区中的实际数据。我现在所做的事情(提交事务或关闭pm然后再获得另一个事务)应该可以正常工作,因为你已将datastoreReadPolicy设置为STRONG。
答案 1 :(得分:2)
Franz,JDO Config中的默认读取一致性是STRONG。所以如果你试图在那个方向接近它,它就不会引导你到任何地方
检查一下,因为我认为它提到了与你遇到的场景类似的东西,提交的数据没有在查询中返回。如上所述它并不是并发的,但它解释了提交过程。
http://code.google.com/appengine/articles/transaction_isolation.html
另外,另一种方法是使用Extents进行查询,并查明是否解决了您正在查看的特定用例,因为我相信您正在提取表中的所有记录。
编辑:
因为在您提到的代码段中,它会查询整个表。如果这就是你所需要的,你可以使用一个范围...... 使用它的方法是通过调用
Extent ext = getExtent(<Entity Class name>)
在persistenceManager单例对象上。然后,您可以遍历范围
查看文档并在此处搜索范围。 http://code.google.com/appengine/docs/java/datastore/jdo/queries.html
答案 2 :(得分:1)
我遇到了同样的问题但这并没有帮助。因为它似乎是谷歌在eclipse&#34; jdo app引擎一致性方面的最佳结果。我想我会为我分享修复工具!
原来我使用PersistenceManagerFactory的多个实例导致了一些奇怪的行为。修复是每个代码访问一个单例。实际上这是GAE教程documented correctly,但我认为它的重要性是低估的。
获取PersistenceManager实例
应用程序使用PersistenceManager的实例与JDO交互 类。您可以通过实例化和调用方法来获取此实例 PersistenceManagerFactory类的一个实例。工厂使用 用于创建PersistenceManager实例的JDO配置。
因为PersistenceManagerFactory实例需要时间来初始化, 应用程序应该重用单个实例。一种简单的方法来管理 PersistenceManagerFactory实例是创建单例包装器 具有静态实例的类,如下所示:
<强> PMF.java 强>
import javax.jdo.JDOHelper; import javax.jdo.PersistenceManagerFactory; public final class PMF { private static final PersistenceManagerFactory pmfInstance = JDOHelper.getPersistenceManagerFactory("transactions-optional"); private PMF() {} public static PersistenceManagerFactory get() { return pmfInstance; } }