-2

当我运行我再次尝试过的代码时出现此异常,但我不断收到问题是学生无法进行测试,因为这次有人给它测试同步类型的错误即将到来

.....:

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

我的代码:

公共同步 StudentAnswer saveAnswer(User user, String assignmentid, String answerid, String answer) throws Exception {

    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;
}
4

2 回答 2

0

这可能意味着在提交事务之前,您尝试更新的行已经被其他线程更新。检查同一条记录是否同时被多个线程处理。

于 2013-02-14T09:39:46.230 回答
0

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

于 2013-02-14T09:50:51.267 回答