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

相關問題