2010-07-26 130 views
2

为什么这给了我一个锁定超时:休眠锁表

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

不介意奇怪的方式,我找到用户:) – AnAmuser 2010-07-26 12:18:29

回答

2

如果您创建一个新的事务(session.beginTransaction();),然后一个新的数据库连接被创建。因此,您有一个事务,它在stats(来自for循环)上有一个读锁定,并且您尝试写入同一行 - > Deadlock。

为了解决这个问题,你首先用第二个循环获取所有StatUser,关闭第一个事务,然后遍历上面代码中的结果。如果因为内存不足而无法执行此操作,则Hibernate不再是您的朋友,您必须使用自定义SQL。

其他解决方案:使用乐观锁定或读取要用自定义SQL更改的数据并实例化循环中的对象。