【问题标题】:Spring-Hibernate used in a webapp,what are strategies for Thread safe session management在 webapp 中使用 Spring-Hibernate,线程安全会话管理的策略是什么
【发布时间】:2010-07-22 13:44:46
【问题描述】:

我正在使用 Spring 和 Hibernate 开发一个 Web 应用程序,我非常着迷于让他的应用程序线程安全并能够支持繁重的负载,因此根据我老板的建议,我最终编写了自己的 session 和 @ 987654323@ 实现session per request pattern。另外我有很多DAOs,我不愿意为所有DAOs写相同的save method我复制粘贴这个Hibernate GenericDAO(我不能说这是同一件事,因为当时休眠不是' t 由 jboss 拥有)并做管道工作,在压力下,所有这些都很快变得复杂并且在生产中,StaleObjectException 和重复的数据是正确的,我觉得是时候回顾一下我所做的事情,简化它并使其对大数据处理更加健壮。您应该知道的一件事是,一个请求涉及多个 DAO。

数据库中有一些更新正在运行。

尽管我想把一切都调得更好,但我没有时间做必要的研究,而且 Hibernate 有点庞大(学习)。

就是这样,我想借用你的经验,问几个问题就知道该往哪个方向走。

问题 1:Hibernate 生成的 uuid 对于线程环境和避免 StaleObjectException 是否足够安全?

问题 2 在 threadSafe 场景中使用休眠 getCurrentSession 的最佳策略是什么(我读过有关 threadlocal 的东西,但没有得到太多理解,所以没有这样做)

问题 3:HIbernateTemplate 是否会采用最简单的解决方案?

问题 4:如果您要为生产服务器实现连接池和调优要求,您会选择什么?

请毫不犹豫地将我指向在线博客或资源,我所需要的只是一种适用于我的场景的方法。如果你要这样做,你的方法。

感谢您阅读本文,欢迎大家的想法......

【问题讨论】:

  • 将 nhibernate 标签更改为休眠

标签: java hibernate spring session


【解决方案1】:

我正在使用 Spring 和 Hibernate 开发一个 Web 应用程序,我非常着迷于让他的应用程序线程安全并能够支持重负载,因此根据我老板的建议,我最终编写了自己的会话和一个会话容器来实现每个请求模式的会话。

您应该删除所有这些代码并改用 Spring/Hibernate API:更少的错误,更少的维护。

我复制粘贴这个 Hibernate GenericDAO(我不能说它是同一件事,因为当时 hibernate 不属于 jboss)并做管道工作,在压力下,一切都很快变得复杂(...)

您可以使用 GenericDao 并使用 Spring 注入所需的东西。

问题 1:Hibernate 生成的 uuid 对于线程环境和避免 StaleObjectException 是否足够安全?

为了严格回答您的问题,以下是参考指南中有关 uuid 生成器的内容:

5.1.4.1. Generator

...

  • uuid

    使用 128 位 UUID 算法 生成字符串类型的标识符 在网络中是唯一的( 使用 IP 地址)。 UUID 是 编码为 32 位十六进制字符串 数字长度。

所以我认为它是安全的。但我认为你的StaleObjectException 是无关的(这是另一个问题)。

问题 2:在 threadSafe 场景中使用 hibernate getCurrentSession 的最佳策略是什么(我读过有关 threadlocal 的东西,但没有得到太多理解,所以没有这样做)

最好的策略是直接使用它,sessionFactory.getCurrentSession() 将始终为您提供一个Session,其范围为当前数据库事务,即“上下文会话”。再次引用参考文档:

2.5. Contextual sessions

大多数使用 Hibernate 的应用程序需要 某种形式的“上下文”会话, 给定会话生效的地方 在给定的范围内 语境。但是,跨应用程序 定义什么构成 上下文通常不同; 不同的语境定义不同的 范围为电流的概念。 之前使用 Hibernate 的应用程序 3.0 版倾向于利用 国产ThreadLocal-based 上下文会话,助手类 例如 HibernateUtil,或利用 第三方框架,例如 Spring 或 Pico,它提供 基于代理/拦截的上下文 会议。

(...)

但是,从 3.1 版开始, 后处理 SessionFactory.getCurrentSession() 现在是可插拔的。为此,一个新的 扩展接口, org.hibernate.context.CurrentSessionContext, 和一个新的配置参数, hibernate.current_session_context_class, 已添加以允许可插入性 定义的范围和背景 当前会话。

请参阅 Javadocs org.hibernate.context.CurrentSessionContext 详细讨论界面 它的合同。它定义了一个单一的 方法,currentSession(),通过它 实施负责 跟踪当前上下文 会议。开箱即用,休眠 带有三个实现 这个界面:

  • org.hibernate.context.JTASessionContext: 跟踪当前会话并 由 JTA 事务限定。这 这里的处理与 在较旧的仅 JTA 方法中。看 有关详细信息,请参阅 Javadocs。
  • org.hibernate.context.ThreadLocalSessionContext: 当前会话由线程跟踪 的执行。请参阅 Javadocs 详情。
  • org.hibernate.context.ManagedSessionContext: 当前会话由线程跟踪 的执行。然而,你是 负责绑定和解除绑定 带有静态方法的会话实例 在这堂课上:它不打开, 刷新或关闭会话。

(...)

现在没有必要实现自己的基于ThreadLocal 的解决方案,不要那样做。

问题 3:HIbernateTemplate 是否会采用最简单的解决方案?

好吧,HibernateTemplate 没有被弃用,但不再推荐,我更喜欢实现template-less DAOs

public class ProductDaoImpl implements ProductDao {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Collection loadProductsByCategory(String category) {
        return this.sessionFactory.getCurrentSession()
                .createQuery("from test.Product product where product.category=?")
                .setParameter(0, category)
                .list();
    }
}

SessionFactory 是由 Spring 注入的。我建议阅读 So should you still use Spring's HibernateTemplate and/or JpaTemplate?? 以了解完整的背景以及 Spring 文档中有关 ORM 数据访问的整个部分 13.3. Hibernate

问题 4:如果您要为生产服务器实现连接池和调整要求,您会选择什么?

嗯……什么?我永远不会实现我的连接池,而是使用我的应用程序服务器中的一个。也许你应该澄清这个问题。

更新: 在生产中,我不会使用 Hibernate 内置连接池,而是将 Hibernate 配置为使用应用程序服务器提供的 JNDI 数据源(以及应用程序服务器连接池)。来自文档:

3.3. JDBC connections

...

这是一个示例 hibernate.properties 文件,用于应用服务器提供的 JNDI 数据源:

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
    org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
    org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

从 JNDI 数据源获得的 JDBC 连接将自动参与应用服务器的容器管理事务。

【讨论】:

  • 感谢 Pascal 为这篇评论付出的所有努力。我几乎就像一篇文章。我正在阅读资源并充分利用那里的所有内容。再次感谢!!
  • @blacksensei:不客气。我试图把有趣的链接放在那里。如果您需要更多说明,请告诉我。
  • 您好,关于问题 4,我问的是关于 hibernate 的连接管理。在网络上在这里和那里你可以找到关于 hibernate 与连接池的教程。所以我问这是否是生产服务器中的最佳实践.pooling,如 c3p0、proxool 和 apache commons jdbc...再次感谢您的宝贵帮助
猜你喜欢
  • 2010-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 2011-09-19
  • 2013-10-03
  • 1970-01-01
相关资源
最近更新 更多