Inconsistent Fetch From Google App Engine Datastore

回眸只為那壹抹淺笑 提交于 2019-12-04 05:48:11
user2855896

I have a suggestion, however you're not gonna like that: use low level API exclusively and forget about JDO / JPA when using GAE.

Just like @asp said, get by ID is supposed to be strongly consistent, however GAE JDO plugin seems bugged to me. Unfortunately, migrating to JPA was no help in my case as well (more here: JDO transactions + many GAE instances = overriding data). Also, if I annotate any class as @PersistenceAware, Eclipse goes crazy, and enhances the classes in infinite loop. Also, I had a lot of problems when using @PersistenceCapable class with embedded class and caching (without caching it worked fine).

Well, the point is, I think it will be way faster with low level API - you know exactly what is happening and it seems to work as intended. You can treat Entity like a Map, with a little bit of self-written wrapping code it seems like a quite interesting alternative. I run some tests and with low level API I passed them no problem, while passing it with JDO/JPA was not possible. I am in the middle of migrating my whole application from JDO to low level API. It is time-consuming, but less than waiting indefinitely for some magical solution or bugfix from GAE team.

Also, while writting GAE JDO I felt... alone. If you have a problem with java, or even android, a thousand of other people already had this problem, asked about it on stackoverflow and got tons of valid solutions. Here you are all by yourself, so use as low level API as possible and you'll be sure whats happening. Even though migration seems scary as hell and time-consuming, I think you'll waste less time migrating to low level API than dealing with GAE JDO/JPA. I don't write it to pinch the team that develops GAE JDO/JPA or to offend them, I'm sure they do their best. But:

  1. There is not so many people using GAE comparing to, lets say, Android or Java in general

  2. Using GAE JDO/JPA with multiple server instances is not that simple and straightforward as you would think. The developer like me wants to have his job done ASAP, see some example, read a bit of documentation - not to study it all in detail, read a short tutorial and the developer has a problem, he would like to share it on stackoverflow and get quick help. Its easy to get help if you do something wrong on Android, no matter if its complicated or its easy mistake. Its not that easy with GAE JDO/JPA. I've spent much more time on GAE JDO articles, tutorials and documentation than I would like to, and I failed to do what I wanted even though it seemed pretty basic. If I just used low level API and not tried to take a shortcut with JDO (yeah, I thought JDO will save my time), it would be much, much quicker.

  3. Google is focused on Python GAE much more than Java. In many articles that are targeted for all the audiences, there is Python code and hints exclusively, quick examples here: http://googlecloudplatform.blogspot.com/2013/12/best-practices-for-app-engine-memcache.html or here: https://cloud.google.com/developers/articles/balancing-strong-and-eventual-consistency-with-google-cloud-datastore/ . I've noticed that even before starting development, but I wanted to share some code with my Android client, so I chose Java. Even though I have solid Java background and even that I do share some code now, if I could go back in time and choose again, I'd choose Python now.

Thats why I think its best to use only the most basic methods to access and manipulate data.

Good luck, I wish you all the best.

asp

If you are using the the High Replication datastore, setting the read policy does not ensure that all reads are strongly consistent, those only work for ancestor queries. From the documentation;

The API also allows you to explicitly set a strong consistency policy, but this setting will have no practical effect, since non-ancestor queries are always eventually consistent regardless of policy.

https://cloud.google.com/appengine/docs/java/datastore/queries#Java_Data_consistency https://cloud.google.com/appengine/docs/java/datastore/jdo/overview-dn2#Setting_the_Datastore_Read_Policy_and_Call_Deadline

Please have a look at the document about Structuring Data for Strong Consistency, the preferred approach is to the caching layer to serve the data.

I noticed that you are using get by ID, not sure, but "get by key" is supposed to be strongly consistent even for HR datastore (reference), can you try changing this to query based on the key? Key is built using the id and the entity kind and ancestry.

Add @Cacheable(value = "false") in entity class. This issue will be resolved.

Above issue mainly due to the JDO cache. So if we disable the cache, JDO will read the data from datastore.

Or you can disable L2 cache in jdoconfig.xml.

Ref Link : http://www.datanucleus.org/products/accessplatform_3_0/jdo/cache.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!