спящий заблокированный стол - PullRequest
2 голосов
/ 26 июля 2010

Почему это дает мне тайм-аут блокировки:

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");
            }
        }

1 Ответ

2 голосов
/ 26 июля 2010

Если вы создаете новую транзакцию (session.beginTransaction();), то создается новое соединение с БД. Итак, у вас есть транзакция с блокировкой чтения на stats (из цикла for), и внутри нее вы пытаетесь записать в ту же строку -> Deadlock.

Чтобы исправить это, вы сначала выбираете все StatUser s со вторым циклом, закрываете первую транзакцию, а затем перебираете результат в приведенном выше коде. Если вы не можете сделать это из-за недостатка памяти, Hibernate больше не ваш друг, и вы должны использовать пользовательский SQL.

Другие решения: используйте оптимистическую блокировку или прочитайте данные, которые будут изменены с помощью пользовательского SQL, и создайте экземпляры объектов в цикле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...