我有一个servlet,可以保存人们上传的代码。他们可以上传多个代码文件,然后将其密钥保存在代码集合中。一切都适用于一个请求。在第一次请求之后,代码JDO类默默地无法持久化。默默地,因为在应用程序中的任何地方都没有一个例外,即使使用它认为tx已关闭并提交的事务。
以下是我正在做的事情:
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
List<Key> uploadedCodeKeys = new ArrayList<Key>();
List<Code> uploadedCode = new ArrayList<Code>();
if(req.getParameterValues("code") == null) {
resp.sendRedirect("/");
}
for(int i = 0; i < req.getParameterValues("code").length; i++) {
String pastedCode;
String language;
String fileName;
try {
language = req.getParameterValues("language")[i];
pastedCode = req.getParameterValues("code")[i];
fileName = req.getParameterValues("filename")[i];
if(pastedCode == null || pastedCode.equals("")) {
pastedCode = "";
}
if(language == null) {
language = "Plain Text";
}
if(fileName == null) {
fileName = "Untitled";
}
} catch (Exception e) {
}
Code code = new Code(pastedCode, language);
code.setFileName(fileName);
uploadedCodeKeys.add(code.getKey());
uploadedCode.add(code);
}
PersistenceManager pm = GAEModel.get().getPersistenceManager();
Transaction tx = pm.currentTransaction();
long id = 0;
try {
tx.begin();
log.info("Attempting to save " + uploadedCode.size() + " files");
pm.makePersistentAll(uploadedCode);
tx.commit();
if(tx.isActive()) {
log.severe("Failed to save code files!");
tx.rollback();
pm.close();
return;
}
CodeCollection cc = new CodeCollection(uploadedCodeKeys);
pm.makePersistent(cc);
id = cc.getKey().getId();
} catch(Exception e) {
log.log(Level.SEVERE, "Failed to save files!", e);
} finally {
pm.close();
}
我正在为代码分配一个字符串哈希或其他东西,它不是重复的。我已经尝试了几乎所有可以想到的持续存在的变化。每次使用非持久代码文件的id存储codecollection。
由于
此处还有来自DEBUG级别失败的提交的日志:
ms = 115 cpu_ms = 168 api_cpu_ms = 98 cpm_usd = 0.004754 I 2011-05-24 20:54:17.424 com.mikehershey.paste.server.URLDispatcher doFilter:加载pageUpload 我2011-05-24 20:54:17.428 org.datanucleus.ObjectManagerImpl close:提交给数据存储区的未完成的nontx更新 I 2011-05-24 20:54:17.482 org.datanucleus.ObjectManagerImpl close:提交给数据存储区的杰出nontx更新
这是一个提交的日志(实例的第一个始终有效): http://pastebin.com/xW6xbfzK
如果我将两个提交都放在tx代码中,即使是第一次也不会保留:
PersistenceManager pm = GAEModel.get().getPersistenceManager();
Transaction tx = pm.currentTransaction();
try {
tx.begin();
log.info("saving code file!");
pm.makePersistentAll(uploadedCode);
tx.commit();
} finally {
pm.close();
}
pm = GAEModel.get().getPersistenceManager();
tx = pm.currentTransaction();
try {
tx.begin();
CodeCollection cc = new CodeCollection(uploadedCodeKeys);
pm.makePersistent(cc);
id = cc.getKey().getId();
tx.commit();
} finally {
pm.close();
}
以上从不保存List(代码),但始终保存CodeCOllection。 当我注释掉转换时,CodeCollection仍然总是被保存,但List(代码)仅保存用于第一次请求实例。所有后续请求都无法保持代码(静默)
PersistenceManager pm = GAEModel.get().getPersistenceManager();
//Transaction tx = pm.currentTransaction();
try {
//tx.begin();
log.info("saving code file!");
pm.makePersistentAll(uploadedCode);
//tx.commit();
} finally {
pm.close();
}
pm = GAEModel.get().getPersistenceManager();
//tx = pm.currentTransaction();
try {
//tx.begin();
CodeCollection cc = new CodeCollection(uploadedCodeKeys);
pm.makePersistent(cc);
id = cc.getKey().getId();
//tx.commit();
} finally {
pm.close();
}
答案 0 :(得分:1)
你的第一个坚持是txn,而你的第二个坚持不是。第二个可能不会与GAE / J使用的那个版本的DataNucleus(即古代)一起运行。把它放在txn中,或者在它之后运行一个txn(tx.begin(); tx.commit();)以便刷新剩余的更新。
答案 1 :(得分:1)
如果未指定注释,则App引擎将事物默认为Persistent。我在CodeCollection中有一个用于缓存Code列表的字段,app引擎试图坚持这个并且它吓坏了。添加了@notpersistent清除了所有内容。