2013-02-14 35 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

我假设你的问题是你为什么得到这个异常以及如何解决它。如果系统对并发更新的容忍度为零,则在查询中使用悲观锁定,但必须确保在短事务中获得锁定,否则会出现性能问题。 或者更好的解决方案是使用乐观锁(使用版本字段)并检查版本是否等于最新版本,如果不可能发送消息给用户说数据已过期。

相关问题