0

现在调查问题一段时间。所以问社区。 我的目标是获取具体类型的所有实体,它们都需要更新。 (没有考虑到现在的任何事务隔离 - 可脏读)GAE/J-JDO按实体类型选择返回过期结果

我用GAE/J-JDO为(使用tx.begin()的只是一个预防措施):

PersistenceManager pm = PMF.get().getPersistenceManager(); 
    Transaction tx = pm.currentTransaction(); 
    Query q = pm.newQuery(TokenJdo.class); 
    List<TokenJdo> tokenList = (List<TokenJdo>) q.execute(); 
    Collection<TokenJdo> res = Collections.unmodifiableCollection(tokenList); 
    tx.commit(); 
    pm.close(); 
    for (TokenJdo t : tokenList) { 
     log.info(t.getToken() + " - " + t.getCounter()); 
    } 

这样做会给我过时的实体(我要求一个列表,去AppEngine控制台并修改一个实体,再次请求一个列表)。 因此,我直接使用DatastoreService编写了以下调试代码。

DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); 
    com.google.appengine.api.datastore.Query gaeQuery = new com.google.appengine.api.datastore.Query(TokenJdo.class.getSimpleName()); 
    PreparedQuery pq = ds.prepare(gaeQuery); 
    List<Entity> list = pq.asList(FetchOptions.Builder.withDefaults()); 
    for (Entity i : list) { 
     log.info(i.getKey() + " - " + i.getProperties()); 
    } 

执行的代码两片在一个请求给出以下输出,并显示通过JDO数据与过时的东西DatastoreService返回:

I 2013-03-20 12:31:16.950 com.serverside.bl.TokenProviderJdo getAll: dummy - -999 
I 2013-03-20 12:31:16.950 com.serverside.bl.TokenProviderJdo getAll: asd - 0 
I 2013-03-20 12:31:16.951 com.serverside.bl.TokenProviderJdo getAll: dummy-aaa - -111 
I 2013-03-20 12:31:16.957 com.serverside.bl.TokenProviderJdo logDSEntities: TokenJdo(7003) - {token=dummy, counter=-999} 
I 2013-03-20 12:31:16.957 com.serverside.bl.TokenProviderJdo logDSEntities: TokenJdo(12001) - {token=asd, counter=0} 
I 2013-03-20 12:31:16.957 com.serverside.bl.TokenProviderJdo logDSEntities: TokenJdo(13001) - {token=dummy-aaa, counter=-222} 

显然(或者因为它看起来对我来说)JDO用途某种内部缓存(L1或L2,尽管我没有明确地启用)。我如何让JDO做一个'干净的'阅读?

回答

0

从高速缓存任何东西阻止datanucleus你应该禁用这两个缓存级别:

datanucleus.cache.level1.type=none 
datanucleus.cache.level2.mode=none 

或者您可以使用QueryQuery禁用缓存或每PersistenceManager,只需设置提到键的或PersistenceManager的方法。

另一方面,您应该在查看它们后需要使用它们时分离出对象。我不太确定这个技术原因,因为PersistenceManager应该在使用它的方法返回之前关闭,或者我学会了,但在禁用所有缓存之后,必须在使用它之前完全分离查找的对象。

+0

关闭L1缓存几乎不应该完成,除非您想冒相同对象的多个副本。在某些情况下关闭二级缓存很有意义,虽然属性应该是datanucleus.cache.level2.type – 2013-03-21 07:16:44

+0

谢谢穆罕默德!这帮助我找到解决问题的最后一步。但实际上我没有找到如何设置每个'PM'或'Query'的L2属性,并且我不想在'PMF'中全局禁用L2。所以在我的情况下,正确的解决方案是在'PM'实例上设置'setIgnoreCache(true)'。 – yny 2013-03-21 08:58:33

+0

@NeilStockton,据我所知,但这是我可以为我的应用程序始终查找数据库中的对象所做的唯一事情,因为我可能使用其他工具更新数据库中的记录,但这些更改未反映在我的应用程序中。如果你分享了如何在不禁用L1缓存的情况下完成,我将不胜感激。谢谢 – 2013-03-21 11:29:22

相关问题