2010-08-24 85 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

你怎么办?因为查询不能转换为Vector。例如,当我试图 载体 questions =(矢量)query.execute(req.getParameter(“date”)); 我有这个: org.datanucleus.store.appengine.query.StreamingQueryResult不能转换为java.util.Vector – ld493 2010-08-25 17:11:11