- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我无法解决 Google App Engine JDO 实现方面的问题。文档 ( http://code.google.com/intl/sv-SE/appengine/docs/java/datastore/jdo/creatinggettinganddeletingdata.html ) 指出“对 makePersistent() 的调用是同步的,并且在保存对象和更新索引之前不会返回。”但我的经验不同。
我想将对象保存 (makePersistent) 到数据存储中。保存完成后,我希望能够立即从数据存储中获取它(执行查询)。我知道我不必获取它(因为我已经在内存中拥有该对象)但关键是我希望下一个请求能够从数据存储中检索数据。如果第二个请求足够快,那不适用于当前的实现。
我注意到的一件奇怪的事情是,如果我试图在一个循环(下面的代码)中多次从数据存储中获取对象,那么对象返回的速度非常快(通常 < 10 毫秒)。但是,如果我跳过循环,而是在 makePersistent 和查询执行之间运行 Thread.sleep(..) 5000 毫秒,则不确定是否找到该对象。这些解决方案都不是我想要的。我希望能够立即获取数据,而无需休眠或在两者之间循环。
下面访问 DataStoreTestServlet 的代码和结果如您所见,包括“等待”找到数据的循环。同样,我不想要循环。
有人知道我错过了什么吗?我想它一定是什么东西。这个实现对我来说不合适 :)。
我使用的是 appengine-java-sdk-1.6.0。这在本地(开发服务器)和部署在 Google 服务器上时都是一个问题。
这是访问 servlet 的结果。
Created users:
User [password=password, userName=user1321190966416] took 18ms, 2 loop(s)
User [password=password, userName=user1321190966438] took 15ms, 6 loop(s)
User [password=password, userName=user1321190966456] took 2ms, 1 loop(s)
User [password=password, userName=user1321190966460] took 10ms, 5 loop(s)
User [password=password, userName=user1321190966472] took 0ms, 1 loop(s)
User [password=password, userName=user1321190966472] took 0ms, 1 loop(s)
User [password=password, userName=user1321190966472] took 16ms, 1 loop(s)
User [password=password, userName=user1321190966488] took 0ms, 2 loop(s)
User [password=password, userName=user1321190966488] took 0ms, 1 loop(s)
User [password=password, userName=user1321190966488] took 16ms, 1 loop(s)
代码和配置。
jdoconfig.xml
<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
<persistence-manager-factory name="transactions-optional">
<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"/>
<property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" />
</persistence-manager-factory>
</jdoconfig>
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;
}
}
用户.java
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class User {
@PrimaryKey
@Persistent
private String userName;
@Persistent
private String password;
public User(String userName, String password) {
super();
this.setUserName(userName);
this.setPassword(password);
}
public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}
public void setUserName(String userName) {
this.userName = userName;
}
public void setPassword(String password) {
this.password = password;
}
public String toString() {
return "User [password=" + password + ", userName=" + userName + "]";
}
}
DataStoreTestServlet.java
import java.io.IOException;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class DataStoreTestServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
StringBuffer sb = new StringBuffer();
sb.append("Created users:\n");
for (int i = 0; i < 10; i++) {
String uniqueName = "user" + System.currentTimeMillis();
User user = new User(uniqueName, "password");
save(user);
User userFromDS = null;
long startTime = System.currentTimeMillis();
long loop = 0;
while (userFromDS == null) {
userFromDS = get(uniqueName);
loop++;
if (userFromDS != null) {
long endTime = System.currentTimeMillis();
sb.append(userFromDS.toString() + " took " + (endTime - startTime) + "ms, " + loop + " loop(s)\n");
}
}
}
resp.setContentType("text/plain");
resp.getWriter().println(sb.toString());
}
public Object save(Object obj) {
PersistenceManager pm = PMF.get().getPersistenceManager();
Object savedObject = null;
try {
savedObject = pm.makePersistent(obj);
} finally {
pm.close();
}
return savedObject;
}
public User get(String userName) {
User user = null;
List<User> users = null;
PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery(User.class);
query.setFilter("userName == nameParam");
query.declareParameters("String nameParam");
try {
users = (List<User>) query.execute(userName);
if (users != null && users.size() > 0) {
user = users.get(0);
}
} finally {
query.closeAll();
pm.close();
}
return user;
}
}
最佳答案
尝试将此添加到您的 jdoconfig.xml 中:
<property name="datanucleus.appengine.datastoreReadConsistency" value="STRONG" />
提高性能; App Engine 数据存储是“最终一致的”。这意味着当您创建新对象或更改现有对象时,它不会立即显示出来;允许查找时间的性能提升。与此相反的是“强”一致性,这意味着每个请求都是使用数据存储中的最新数据发出的。
现在,根据app engine documentation for this STRONG 一致性是默认值,您必须显式设置最终一致性。但是,根据我的观察,您必须设置 STRONG 一致性,而 EVENTUAL 是默认设置(可能是错误?)。因此,请尝试将以上内容添加到您的 jdoconfig xml 中,如果您观察到我所做的相同事情,那么我可能会打开一个针对应用引擎的错误,假设尚未针对此问题打开一个错误。
您必须牢记的一件事是,如果您设置了“强一致性”,您的性能将会受到影响。我设置它只是因为我的界面的某些部分变得困惑,因为我会用不太新鲜的数据构建它的一部分,而在同一个请求中,另一个部分会用新数据构建;使我的界面不一致。这可能是解决问题的广泛方法;但它有效:)。
关于google-app-engine - Google App Engine JDO makePersistent 延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8112331/
我正在使用连接到 MySQL 数据库的 Spring 和 JDO。当我保留一个对象时,我希望看到由 makePersistent() 方法返回的已创建对象。它确实返回了一个对象,但是这个对象只有新建对
我有一些这样的代码 class root extends DomainObject{ Collection childElements; Collection childElements2; ....
PersistenceManager 的 makePersistent 方法工作不可靠。一个和同一个 junit 测试正在工作,但过了一会儿又失败了?!我有一个对象,其中包含其他对象的集合。这意味着
我无法解决 Google App Engine JDO 实现方面的问题。文档 ( http://code.google.com/intl/sv-SE/appengine/docs/java/datas
当我创建一个同时定义“gae.encoded-pk”和“gae.pk-id”的类持久化时,encoded-pk 会更新,但 id 仍然为空。没有异常被抛出,代码是从谷歌文档中直接复制粘贴的,所以我对这
我是一名优秀的程序员,十分优秀!