2013-02-14 67 views
-2

我得到這個例外,當我運行的代碼 我再次嘗試,但即時得到它不斷地 問題是學生無法給出測試作爲一個人給它的這個時候 同步類型誤差即將行被更新或者被另一個事務刪除

....:

Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) 

我的代碼:

公共同步StudentAnswer saveAnswer(用戶用戶,字符串assignmentid,字符串answerid,絃樂答案)拋出異常{

if (user == null || user.getStudent() == null) 
     throw new GeneralSecurityException("Permission Denied"); 

    Auditor auditor = new Auditor(user); 

    AssignmentStatus status = getAssignmentStatus(user, assignmentid); 
    StudentAnswer studentAnswer = getStudentAnswer(user, assignmentid, answerid); 

    Object oldStatus = auditor.clone(status, new AssignmentStatus()); 
    //Object oldAnswer = auditor.clone(studentAnswer, new StudentAnswer()); 
    Object oldAnswer = auditor.clone((studentAnswer == null) ? new StudentAnswer() : studentAnswer, new StudentAnswer()); 
    Date now = new Date(); 

    if (status != null && status.isCompleted()) 
     return studentAnswer; 

    if (studentAnswer == null) { 

     Assignment assignment = getAssignment(user, assignmentid); 
     AnswerKey answerKey  = (AnswerKey) genericDao.get(AnswerKey.class, answerid); 

     if (answerKey == null) 
      throw new Exception("There was an error trying to save an answer."); 

     if (status == null) 
      status = startAssignment(user, assignment, now); 

     if (status == null) 
      throw new Exception("There was an error trying to start the assignment."); 

     studentAnswer = new StudentAnswer(); 
     studentAnswer.setStudent(user.getStudent()); 
     studentAnswer.setCreateTime(now); 
     studentAnswer.setAssignmentStatus(status); 
     studentAnswer.setAssignment(assignment); 
     studentAnswer.setAnswerKey(answerKey); 
     studentAnswer.setQuestionNumber(answerKey.getNumber()); 
     studentAnswer.setAnswerKeyCopy(answerKey.getAnswer()); 

     //Adding a new answer changes your progress percentage, so we recalculate it 
     updateProgress(status, now, answer); 

    } 
    //changing existing answer 
    else { 
     Long practiceId = studentAnswer.getAnswerKey().getPractice().getObjectid(); 

     PracticeStatus practiceStatus = null; 
     for (PracticeStatus tmpPracticeStatus : (List<PracticeStatus>) status.getPracticeStatuses()) { 
      if (tmpPracticeStatus.getCustomPractice().getPractice().getObjectid().longValue() == practiceId.longValue()) { 
       practiceStatus = tmpPracticeStatus; 
      } 
     } 

     //completed practice due to time out or submit? Don't change the 
     //answer. 
     if (practiceStatus != null && practiceStatus.isCompleted()) { 
      throw new Exception("Time is up for this practice, so answers may no longer be changed."); 
      //return studentAnswer; 
     } 

    } 

    if (answer!=null && answer.length() > 0) 
     studentAnswer.setAnswer(answer.charAt(0)); 
    else 
     studentAnswer.setAnswer(' '); 

    studentAnswer.setUpdateTime(now); 


    studentAnswer = (StudentAnswer) genericDao.save(studentAnswer); 

    updateGrade(status); 
    updateProgress(status, now, null); 
    genericDao.save(status); 

    auditor.audit("answer_save", status, oldStatus); 
    auditor.audit("answer_save", studentAnswer, oldAnswer); 
    genericDao.saveList(auditor.getList()); 

    return studentAnswer; 
} 
+1

你的問題是什麼? – spiritwalker 2013-02-14 09:39:24

+0

只是發佈你的代碼和異常並沒有真正的幫助。你的代碼縮進了什麼?你在哪一行得到例外? – 2013-02-14 09:39:51

+0

P.S.在最後一行中不應該有'studentAnswer'而不是'asnwer':'updateProgress(status,now,answer);'? – 2013-02-14 09:41:44

回答

0

這可能意味着你要更新該行已經被其他線程更新是越來越致力於交易前。檢查同一條記錄是否被多個線程同時處理。

0

我假設你的問題是你爲什麼得到這個異常以及如何解決它。如果系統對併發更新的容忍度爲零,則在查詢中使用悲觀鎖定,但必須確保在短事務中獲得鎖定,否則會出現性能問題。 或者更好的解決方案是使用樂觀鎖(使用版本字段)並檢查版本是否等於最新版本,如果不可能發送消息給用戶說數據已過期。

相關問題