谷歌应用程序引擎在第一次坚持后默默地坚持失败
我有一个 servlet 可以保存人们上传的代码。他们可以上传多个代码文件,然后将其密钥保存在代码集合中。一切都只针对一个请求。第一次请求后,Code JDO 类无法持久保存。默默地,应用程序中的任何地方都没有任何异常,即使使用事务,它也认为交易已关闭并提交。
这就是我正在做的事情:
@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 一起存储。
谢谢
这里还有在调试级别失败的提交的日志:
ms=115 cpu_ms=168 api_cpu_ms=98 cpm_usd=0.004754 我 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:未完成的非tx更新正在提交到数据存储 我 2011-05-24 20:54:17.482 org.datanucleus.ObjectManagerImpl close:未完成的非tx更新正在提交到数据存储
这是一个确实提交的日志(实例的第一个始终有效): 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(Code),但总是保存CodeCOllection。 当我注释掉事务时,CodeCollection 仍然始终保存,但是 List(code) 仅在对实例的第一个请求时保存。所有后续请求都无法持久保存代码(沉默)
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();
}
I have a servlet that is saving code people upload. They can upload multiple code files whose keys are then saved in a code collection. Everything works for exactly one request. After the first request the Code JDO class silently fails to be persisted. Silently as in there is not a single exception anywhere in the app, even using transactions it thinks the tx is closed and commited.
Here is what I'm doing:
@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();
}
I'm assigning code a string hash or something, its not a duplicate. I've tried nearly every variation that last few lines that persist that I can think of. The codecollection gets stored everytime with the id's of the nonpersisted code files.
Thanks
Also here are logs from a commit that fails on DEBUG level:
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: loading pageUpload
I 2011-05-24 20:54:17.428
org.datanucleus.ObjectManagerImpl close: Outstanding nontx update being committed to datastore
I 2011-05-24 20:54:17.482
org.datanucleus.ObjectManagerImpl close: Outstanding nontx update being committed to datastore
Heres a log that does commit (the first one of an instance always works):
http://pastebin.com/xW6xbfzK
If I put both commits in a tx Code is never persisted even the first time:
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();
}
The above never saves the List(Code) but always saves the CodeCOllection.
When I comment out the tranactions CodeCollection is still always saved, however List(code) is only saved for the first request to an instance. All subsequent requests fail to persist code (silenty)
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的第一个持久是在 txn 中,而你的第二个不是。第二个可能无法与 GAE/J 使用的 DataNucleus 版本(即古代版本)一起运行。将其放入 txn 中,或在其后运行 txn (tx.begin(); tx.commit();) 以刷新剩余的更新。
your first persist is in a txn, and your second is not. The second will likely not run with that version of DataNucleus that GAE/J uses (i.e ancient). Put it in a txn, or run a txn after it (tx.begin(); tx.commit();) for the remaining updates to be flushed.
如果未指定注释,App Engine 将默认设置为“持久”。我在 CodeCollection 中有一个字段用于缓存代码列表,应用程序引擎试图保留此字段,但结果很糟糕。添加了 @notpersistent 清除了一切。
App engine defaults things to Persistent if no annotation is specified. I had a field in CodeCollection that was used to cache a list of Code, app engine was trying to persist this and it was freaking out. Added a @notpersistent cleared everything up.