2012-12-01 97 views
2

我刚刚开始使用AppEngine,但在数据存储中遇到了一些问题。Appengine和JPA - 读取刚刚写入的数据

我想使用JPA将一些数据写入数据存储。我一直在使用留言板示例来关注Appengine网站上的Java示例,并且我想将此留言簿示例翻译为使用JPA 2.0。

当我在我的输出中运行具有我的数据存储中已有的一些数据(使用先前运行创建的)的应用程序时,它显示我在写入前有7个项目,然后写入就可以,之后再次给我7项。但是,如果我打开我的管理控制台(http:// localhost:8888/_ah/admin/datastore?kind = Greeting),我可以看到数据存储区中已有8个项目。所以出于某种原因,我正在遭受幻像读取......

我所有的代码如下所示。

有没有人有想法我做错了什么?

这是我的persistence.xml看起来像: http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd”版本= “1.0”>

<persistence-unit name="transactions-optional"> 
    <provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider> 
    <properties> 
     <property name="datanucleus.NontransactionalRead" value="true"/> 
     <property name="datanucleus.NontransactionalWrite" value="true"/> 
     <property name="datanucleus.ConnectionURL" value="appengine"/> 
    </properties> 
</persistence-unit> 

这是代码:

 EntityManagerFactory emf = EMF.get(); 
     EntityManager em = emf.createEntityManager(); 
     try { 
      em.getTransaction().begin(); 

      // Reading the data 
      javax.persistence.Query query = em.createQuery("SELECT FROM Greeting g"); 
      List<Greeting> greetings = query.getResultList(); 
      for (Greeting g : greetings) { 
       log.info("Greeting found: " + g.getContent()); 
      } 
      log.info("Number of greetings found before writing: " + greetings.size()); 

      // Storing the data 
      Greeting greeting = new Greeting(); 
      greeting.setUser(user); 
      greeting.setDate(new Date()); 
      greeting.setContent(content); 

      em.persist(greeting); 
      em.flush(); 

      // Reading the data 
      query = em.createQuery("SELECT FROM Greeting g"); 
      greetings = query.getResultList(); 
      for (Greeting g : greetings) { 
       log.info("Greeting found: " + g.getContent()); 
      } 
      log.info("Number of greetings found after writing: " + greetings.size()); 
      em.getTransaction().commit(); 
     } catch (Exception e) { 
      log.warning("Cannot write to database because of error: " + e.getMessage()); 
      e.printStackTrace(); 
     } finally { 
      em.close(); 
      emf.close(); 
     } 

回答

0

谷歌AppEngine上不支持那种数据库的一致性,而不是在后台复制数据库,为每一位w ^仪式,他们同时写入> 50%的副本,并在稍后完成复制。所以,如果你写,然后立即阅读,你的阅读可能会击中尚未复制的副本。

你只需要改变你的代码,以避免写后读。通常这不应该是一个问题,因为它已经在内存中。

https://developers.google.com/appengine/docs/java/datastore/structuring_for_strong_consistency

要更改设置在Eclipse中,转到项目>右键点击>谷歌> AppEngine上设置>运行配置> Web应用程序>您的项目>的App Engine>高复制设置(HRD)未核销工作百分比> 50.此值模拟在写入开发之后读取失败的百分比。 0%=正常数据库(但会在生产中失败)。

JPA位于Datastore API之上,因此它遭受同样的问题。