帮我找到僵局

时间:2011-04-13 17:42:28

标签: java hibernate deadlock

这是我第一次亲眼看到这段代码,我们陷入僵局。

Caused by: java.sql.BatchUpdateException: Lock wait timeout exceeded; try restarting transaction

这是代码:(Java /伪代码)

// This function inside a Job implementation of Quartz Job
execute(...)
{
     UserTransaction trans = getTransaction();
     trans.begin();

     Session session = getSession();

     List<PersistedObject> list = getListOfPersistedObjects(...)

     int counter = 0;
     loop(l : list)
     {
           counter++;

          // this is just sending a message using information based on the object
           sendMessage(l); 

           // Create a 2nd "archive" object based on the data inside the l object
           PersistedObjectArchive archive = new PersistedObjectArchive(l)

           session.save(archive);
           session.flush();

           session.delete(l);
           session.flush();

           if(counter % JDBC_BATCH_SIZE_CONSTANT_FROM_SOMEWHERE == 0)
           {
                session.flush(); // Deadlock Exception happens here
                session.clear();
           }
     }

     trans.commit();
}

我认为上面的代码可以清理一下 - 我没有看到使用这么多的刷新,但我现在只是使用现有的代码。

有人注意到导致死锁的原因吗?

2 个答案:

答案 0 :(得分:2)

这不是数据库中的死锁,等待另一个数据库会话持有的锁时超时。您应该在Hibernate中启用SQL日志记录,并在抛出异常之前查看应用程序正在执行的操作。您还可以使用Oracle的动态性能视图从数据库中获取更多信息。例如,从V $ LOCK中选择以查找当前持有的锁;您可能需要将此加入V $ SESSION以了解有关锁定器的更多信息。

答案 1 :(得分:0)

由于异常,我认为问题不在此代码中,我认为这是数据库中的时间。

顺便说一句:你应该重新考虑处理交易的方式。我认为在某些情况下try{...}finally{trans.rollback);}会有所帮助。