Google App Engine продолжает молчать сбой после первого сохранения - PullRequest
1 голос
/ 25 мая 2011

У меня есть сервлет, который сохраняет код, загружаемый людьми. Они могут загружать несколько файлов кодов, ключи которых затем сохраняются в коллекции кодов. Все работает ровно по одному запросу. После первого запроса класс 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();
    }

Я присваиваю коду строковый хеш или что-то, а не дубликат. Я перепробовал почти все варианты, которые сохранились в нескольких последних строках, которые я могу придумать. Коллекция кода хранится каждый раз вместе с идентификаторами файлов неперспективного кода.

Спасибо

Также вот журналы от коммита, который терпит неудачу на уровне DEBUG:

мс = 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: загрузка страницыЗагрузка I 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();
    }

Вышеприведенное никогда не сохраняет список (код), но всегда сохраняет кодовую коллекцию. Когда я закомментирую транзакции, CodeCollection все равно всегда сохраняется, однако список (код) сохраняется только для первого запроса к экземпляру. Все последующие запросы не могут сохранять код (без звука)

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 ]

1 голос
/ 25 мая 2011

Движок приложения по умолчанию настроен на Постоянный, если аннотации не указаны. У меня было поле в CodeCollection, которое использовалось для кэширования списка кодов, движок приложений пытался сохранить это, и он выходил из себя. Добавил @notpersistent, всё прояснило.

1 голос
/ 25 мая 2011

ваш первый персистент находится в txn, а ваш второй нет.Второй, скорее всего, не будет работать с той версией DataNucleus, которую использует GAE / J (т.е. древняя).Поместите его в txn или запустите txn после него (tx.begin (); tx.commit ();) для сброса оставшихся обновлений.

...