开发者

problem transaction commit, retry , ConcurrentModificationException

开发者 https://www.devze.com 2023-01-12 18:47 出处:网络
i\'ve got some problems with transactions when there is the exception java.util.ConcurrentModificationException.

i've got some problems with transactions when there is the exception java.util.ConcurrentModificationException.

When i've got this exception, i tried a retry but when i'm looking in my datastore viewer my incrementation didn't work.

For example when i'm testing with 30 simultaneous users, my data was incremented 28 times. 2 incrementations are missing and i've got 2 java.util.ConcurrentModificationException.

Somebody knows why? How can i solve this problem.

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

my method increment in a java class

pu开发者_Python百科blic void increment() {
    counter ++;
}


Use Vector instead of List. When you run the query and return a list, modifications of that list are persisted in the datastore when the transaction is committed. Therefore, if you have many users trying to modify this list at once, you'll run into this exception because they are all trying to modify the same list that is in the datastore. Use Vector, since it is synchronized, and your problem will go away.


I solve my problem by using key and the method pm.getObjectById instead of query

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号