这是我第一次亲眼看到这段代码,我们陷入僵局。
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();
}
我认为上面的代码可以清理一下 - 我没有看到使用这么多的刷新,但我现在只是使用现有的代码。
有人注意到导致死锁的原因吗?
答案 0 :(得分:2)
这不是数据库中的死锁,等待另一个数据库会话持有的锁时超时。您应该在Hibernate中启用SQL日志记录,并在抛出异常之前查看应用程序正在执行的操作。您还可以使用Oracle的动态性能视图从数据库中获取更多信息。例如,从V $ LOCK中选择以查找当前持有的锁;您可能需要将此加入V $ SESSION以了解有关锁定器的更多信息。
答案 1 :(得分:0)
由于异常,我认为问题不在此代码中,我认为这是数据库中的时间。
顺便说一句:你应该重新考虑处理交易的方式。我认为在某些情况下try{...}finally{trans.rollback);}
会有所帮助。