单线程独立java应用程序进入死锁?是的,使用EclipseLink这很容易。因此,在调试了一个非常复杂的多线程应用程序一周后,我设法将问题缩小到这个范围:
如果您在应用程序中只有一个线程,则假设您需要一个大小为1的数据库连接池,并且一切都应该正常工作。好吧,不是在这种情况下:
public void singleThreadedMethod() {
User u;
--start JPA transaction / create EM (1)--
u = em.find(User.class, userId);
-- end JPA transaction / close EM --
--start JPA transaction / create EM (2)--
u.getCompany(); // lazy assoc (3)
-- end JPA transaction / close EM--
}
EclipseLink将为(1)接受1个连接,然后将其返回到池中。然后为(2)采用另一个连接,然后尝试为(3)采用另一个连接,尽管看起来代码在单个事务中。诀窍是u
未在此事务中管理(2),但仍然“管理”到达DB以获得其惰性关联。如果DB池大小为1,则会产生死锁,因为(2)保持(3)(inside(2))等待的唯一连接。请注意,这不是DB中的死锁,而是Java中的连接池。
如果您拥有20个连接池且少于20个线程,并且您想知道该死锁来自哪里,这会产生调试噩梦!
我想这是一个很长的镜头,但是 - 有没有办法阻止EclipseLink做它做的事情?即在不在持久化上下文中时阻止它获取延迟关联?或者使用线程的现有持久化上下文(如果存在)。