2010-07-26 6 views
2

Pourquoi cela me donne un délai d'attente de verrouillage:mise en veille prolongée table verrouillée

for(int i = 0; i < playersCount ; i++) { 
      StatUser stats = (StatUser) selectedUsers.get(i).getStatUsers().iterator().next(); 
      int gc = stats.getGamesPlayed(); 
      int gm = stats.getMakeCount(); 

      Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
      Transaction tx = session.beginTransaction(); 
      if(i == winnerIndex) { 
        stats.setGamesPlayed(gc++); 
        stats.setMakeCount(gm++); 
        session.update(stats); 
        session.flush(); 
        tx.commit(); 
        customTextBean.sendMail(selectedUsers.get(i).getEmail(), "Tillykke du har vundet"); 
      } 
      else { 
       stats.setGamesPlayed(gc++); 
       session.update(stats); 
       session.flush(); 
       tx.commit(); 
       customTextBean.sendMail(selectedUsers.get(i).getEmail(), "Tillykke " + winnersName + " skal lave kaffe"); 
      } 
     } 
+0

Ne vous occupez pas de la façon bizarre que je trouve l'utilisateur :) – AnAmuser

Répondre

2

Si vous créez une nouvelle transaction (session.beginTransaction();), puis une nouvelle connexion DB est créé. Donc, vous avez une transaction qui a un verrou en lecture sur stats (à partir de la boucle for) et à l'intérieur de cela vous essayez d'écrire sur la même ligne -> Deadlock.

Pour corriger cela, vous devez d'abord récupérer tous les StatUser s avec une deuxième boucle, fermer la première transaction, puis parcourir le résultat dans le code ci-dessus. Si vous ne pouvez pas faire cela parce que vous manquez de mémoire, Hibernate n'est plus votre ami et vous devez utiliser SQL personnalisé.

Autres solutions: Utilisez un verrouillage optimiste ou lisez les données à modifier avec SQL personnalisé et instanciez les objets dans la boucle.

Questions connexes