2011-05-25 20 views
1

我有一個保存代碼的人上傳的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(); 
    } 

我指定的代碼串的散列或東西,它不是一個副本。我已經嘗試過幾乎所有可以持續下去的線條,我可以想到。 codecollection每次都會使用未被識別的代碼文件的id來存儲。

由於

同樣在這裏是從原木的提交失敗上DEBUG級別:

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:加載頁面上傳 I 2011-05-24 20:54:17.428 org.datanucleus.ObjectManagerImpl關閉:未完成的正在提交給數據存儲的nontx更新 I 2011-05-24 20: 54:17.482 org.datanucleus.ObjectManagerImpl關閉:未完成的正在提交的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。 當我註釋掉傳遞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(); 
    } 
+0

這就是爲什麼你有一個日誌;-)在DEBUG級別 – DataNucleus 2011-05-25 11:06:19

+0

負。 heres所有來自appspot.com的日誌(添加到帖子)他們不適合在這裏。 – mike 2011-05-25 13:10:57

回答

1

如果未指定任何註釋,則應用程序引擎默認爲「持續」。我在CodeCollection中有一個用於緩存代碼列表的字段,應用程序引擎試圖堅持這一點,它嚇壞了。增加了@notpersistent清除了一切。

+0

實際上,JDO和JPA具有默認的東西是否持久,而不是GAE/J。他們的文檔完全是誤導性的,因爲他們暗示你必須在所有內容中指定@Persistent。 – DataNucleus 2011-05-25 15:07:50

1

您的第一個存留是txn,而第二個不存在。第二種可能不會使用GAE/J使用的DataNucleus版本(即古代版本)。把它放在txn中,或者在它後面運行一個txn(tx.begin(); tx.commit();),以便刷新剩餘的更新。

+1

有趣的是第二次提交(codecollection)總是運行。這是tx中的第一個不起作用的工具。我已經更新了我的原始帖子並提供了更多信息 – mike 2011-05-25 14:09:47

相關問題