在分层Spring MVC Web应用程序中处理Hibernate Sessions的最佳方法

时间:2011-07-17 05:51:16

标签: java hibernate spring

如果我们有一个具有

的Web应用程序
  • 重UI(Spring MVC + JQuery with JSON)
  • 使用JPA注释作为域模型的Hibernate
  • 将Spring提供的DAO扩展到代码DAO层
  • JBOSS是Oracle作为后端的应用服务器
  • 基于数据源(JNDI)的连接池(不是XA而非本地数据源)
  • 还可以访问多个数据源(处理多个数据库)

从行为上看,很多数据检索(70%)和数据更新为30% 以下有效消耗数据库连接的最佳实践是什么,并且在连接使用时也没有太多泄漏?

  1. 选择基于Hibernate模板的DAO会更好吗?
  2. 什么样的交易经理可以建议,我们应该选择基于AOP的交易管理
  3. 在何处实例化会话以及在何处关闭会话以有效地消耗来自连接池的连接。
  4. 确实,我们需要处理来自Service层的事务,但是会话会发生什么等待更长的时间(我们没有使用任何opensessioninviewFilter)
  5. 哪个层更好地处理已检查的异常(业务异常)和运行时异常。
  6. 对不起这个有点长的问题,但是我发现这是一个常见的查询,我尝试合并它。感谢您的耐心和指导。谢谢你的帮助。

2 个答案:

答案 0 :(得分:16)

这听起来像是一个非常典型的Spring / Hibernate应用程序,所以我建议遵循我最近在another answer中概述的当前最佳实践。具体做法是:

  1. 扩展Spring DAO支持类或使用HibernateTemplate。将@Repository注释与组件扫描结合使用,并将directly inject the SessionFactory添加到DAO中。
  2. 使用Spring HibernateTransactionManager,绝对使用declarative transaction management @Transactional作为默认方法。
  3. Spring manage that。默认情况下,它会及时为交易打开会话,但更喜欢Spring open session in view pattern启用的OpenSessionInViewFilter
  4. 见#3。
  5. 始终处理应该处理的异常 - 换句话说,这是一个设计决策。但请注意,Spring事务框架默认为rolls back on unchecked exceptions,但未经过检查,以匹配EJB规范的行为。确保在使用已检查异常的任何位置设置正确的回滚规则(请参阅上一个链接)。
  6. 此外,显然使用连接池。 Apache Commons DBCP是一个很好的选择。 “连接使用中没有太多泄漏”是不够的。您必须具有零连接泄漏。根据Spring来管理您的资源将有助于确保这一点。至于任何其他性能问题,不要试图过早优化。等到你看到问题所在的位置,然后找出解决每个问题的最佳方法。由于您的瓶颈很可能与数据库相关,请查看Hibernate参考的the performance chapter以了解您遇到的问题。它涵盖了缓存和获取策略的重要概念。

答案 1 :(得分:2)

  • 直接在您的DAO中使用JPA EntityManager。请勿将其标记为扩展
  • 首选<tx:annotation-driven />@Transactional - 仅限于服务层
  • 事务管理器还会打开和关闭会话(如果线程中已经存在一个会话)。在这里,最好知道会话是每个请求的会话。每个请求(=线程)都有一个单独的会话实例。但是只有在需要时才创建数据库连接,因此即使所有方法都有一个事务管理器,也不会打开不必要的连接。
  • 只读事务 - 在只有数据检索的情况下使用@Transactional(readOnly=true)
  • 缓存 - 利用hibernate二级缓存将实体放入内存(而不是每次从数据库中获取)
  • 避免OpenSessionInView和懒惰的集合。这是主观的,但在我看来,必须初始化离开服务层的所有对象。对于小型集合(例如角色列表),您可以拥有热切的集合。对于更大的集合,请使用HQL查询。