2010-07-26 184 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更改的數據並實例化循環中的對象。