2010-08-24 2 views
2

У меня есть некоторые проблемы с транзакциями, когда есть исключение java.util.ConcurrentModificationException.проблема транзакция фиксация, повтор, 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 ++; 
} 

ответ

0

Я решить мою проблему с помощью ключа и метод 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

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

+0

Как вы это делаете? Потому что запрос не может быть передан в вектор. Например, когда я пытаюсь Векторный questions = (Вектор ) query.execute (req.getParameter ("date")); У меня есть это: org.datanucleus.store.appengine.query.StreamingQueryResult нельзя передать в java.util.Vector – ld493

Смежные вопросы