Java Spring DAO 挂在 return 语句上

Posted

技术标签:

【中文标题】Java Spring DAO 挂在 return 语句上【英文标题】:Java Spring DAO hangs on return statement 【发布时间】:2016-09-12 10:17:30 【问题描述】:

我有一个带有 Oracle DB 和 Hibernate 的 Java Spring 应用程序。在我的控制器中,我正在调用 DAO 来检索一些数据。 DAO 方法继续执行,直到它到达 return 语句,然后它无法返回到控制器。不会抛出异常。相反,它会超时。是这样的

控制器:

 @Autowired
    DAO dao; 

     public @ResponseBody int controller()
          //stuff     
          System.out.println(1); 
          Map<Long, DBObj> objs = dao.getObjMap(ids); 
          System.out.println(3); 
          //other stuff
     

道:

@Transactional
 public Map<Long, DBObj> getObjMap(List<Long> ids)
      //stuff
      System.out.println(2)
      return objs; 
 

输出:

 1
 2

据我所知,它正确地从数据库中检索,所以它似乎不是数据库问题。其他数据库调用工作正常。

从调试器看,它似乎挂在 return 语句的某个地方。具体来说,它似乎在尝试调用 socketRead0 时挂在 SocketInputStream.java 上

编辑:问题与排序有关。我对检索到的对象的子对象进行了排序。返回时,Hibernate 试图进行额外的数据库调用并因此挂起。我通过将父对象传递给调用方法然后在调用方法而不是 DAO 中排序来解决这个问题。

【问题讨论】:

由于您处于事务中,您可能会遇到死锁或其他查询/插入,这在数据库级别上花费的时间太长。 我同意 JustinKSU ...您的提交是否通过?读操作真的需要事务吗? 看起来您的 getObjMap 中的操作需要很长时间。您能否也分享这些代码行 您应该使用调试器查看方法是否真正完成,而不是跟踪。 现在,我正在本地环境中对其进行测试,所以应该不会出现死锁。数据库不是问题,因为我可以在 return 语句之前打印检索到的数据,而且一切看起来都很好。当我删除@Transactional 时,我得到“org.hibernate.HibernateException:没有绑定到线程的 Hibernate 会话,并且配置不允许在这里创建非事务性会话”,所以它似乎是必要的 【参考方案1】:

试试这个:

@Target( ElementType.TYPE, ElementType.METHOD )
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Transactional(
    timeout = 3600,
    rollbackFor =  RuntimeException.class, ApplicationCheckedException.class ,
    noRollbackFor =  ApplicationCheckedNoRollbackException.class, InternalNoRollbackException.class )
public @interface LongTx 

    // Empty.


使用 @LongTx 注释您的方法

@LongTx
 public Map<Long, DBObj> getObjMap(List<Long> ids)
      //stuff
      System.out.println(2)
      return objs; 
 

【讨论】:

刚刚试过这个。没有帮助 - 它挂在同一个地方。我认为这不是数据库问题,因为其他数据库调用工作正常。 你尝试调试了吗 是的,它挂在 return 语句的某个地方。 你在做什么操作......就像我们在那个方法中的代码 //stuff 一样。可以分享一下吗? 基本上,我正在根据 id 列表检索对象列表。然后我将它们放入地图中,这样我就可以通过它们的 ID 轻松获取它们。在将它们放入地图之前,我对这些对象的子对象进行了排序,但这完全是程序化的,不涉及额外的数据库调用。应该很简单。我的休眠标准只是 "criteria.add(Restrictions.in("ID", ids));"【参考方案2】:

请注意,数据库上没有其他事务的锁定,这意味着请注意代码中是否使用了某种锁定机制。

可能有其他事务持有表中记录的锁。

【讨论】:

据我所知,数据库没有问题。我可以调用其他访问数据库的方法就好了,即使是使用相同表的方法。 请查看此帖***.com/questions/23753510/…

以上是关于Java Spring DAO 挂在 return 语句上的主要内容,如果未能解决你的问题,请参考以下文章

面试必考多少Java程序员面试都挂在了它上面!

Spring Java 中许多 DAO 的策略

Spring 数据存储库和 DAO Java 泛型

java - 如何在Java Spring和Hibernate的单个事务中管理2个DAO方法?

spring boot mvc dao java.lang.NullPointerException: null

[刘阳Java]_Spring对Dao的支持_第10讲