首次持续存在后,Google应用引擎会无声地失败

时间:2011-05-25 01:48:29

标签: java google-app-engine web-applications jdo

我有一个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();
    }

2 个答案:

答案 0 :(得分:1)

你的第一个坚持是txn,而你的第二个坚持不是。第二个可能不会与GAE / J使用的那个版本的DataNucleus(即古代)一起运行。把它放在txn中,或者在它之后运行一个txn(tx.begin(); tx.commit();)以便刷新剩余的更新。

答案 1 :(得分:1)

如果未指定注释,则App引擎将事物默认为Persistent。我在CodeCollection中有一个用于缓存Code列表的字段,app引擎试图坚持这个并且它吓坏了。添加了@notpersistent清除了所有内容。