фиксация транзакции, повторная попытка, ConcurrentModificationException - PullRequest
2 голосов
/ 25 августа 2010

У меня есть некоторые проблемы с транзакциями, когда есть исключение java.util.ConcurrentModificationException.

Когда я получил это исключение, я попытался повторить попытку, но когда я смотрю в свою программу просмотра хранилища данных, мой прирост не работает.

Например, когда я тестирую с 30 пользователями одновременно, мои данные были увеличены в 28 раз.2 приращения отсутствуют, и у меня есть 2 java.util.ConcurrentModificationException.

Кто-нибудь знает почему?Как я могу решить эту проблему.

int answerNb = Integer.parseInt(req.getParameter("answer"));
PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery("select from " + Question.class.getName());
query.setFilter("date == dateParam");
query.declareParameters("String dateParam");
List<Question> questions = (List<Question>) query.execute(req.getParameter("date"));

if(!questions.isEmpty()) {
    int retryCount = 0;
    while (retryCount++ < 30) {
      pm.currentTransaction().begin();
      questions.get(0).getAnswers().get(answerNb).increment();

      try {
         pm.currentTransaction().commit();
         break;
      }
      catch (Exception x) {
         //retry
      }
  }

мой инкремент метода в классе Java

public void increment() {
    counter ++;
}

Ответы [ 2 ]

0 голосов
/ 30 августа 2010

Я решаю свою проблему, используя ключ и метод pm.getObjectById вместо запроса

int answerNb = Integer.parseInt(req.getParameter("answer"));            
int retryCount = 0;
Transaction tx;
Question question;

while (retryCount++ < 30) {
  PersistenceManager pm = PMF.get().getPersistenceManager();
  tx = pm.currentTransaction();
  tx.begin();
  question = pm.getObjectById(Question.class,KeyFactory.stringToKey(req.getParameter("key")));          
  question.getAnswers().get(answerNb).increment();
  try {
    tx.commit();
    pm.close();
    break;
  }
  catch (Exception x) {
    pm.close();
    log.info("retry : "+retryCount);
  }
}
0 голосов
/ 25 августа 2010

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

...