Spring-Hibernate在webapp中使用,什么是Thread安全会话管理的策略

bla*_*sei 1 java session spring hibernate

我正在开发一个使用Spring和Hibernate的Web应用程序,我非常痴迷于使应用程序线程安全,并且能够支持基于我的老板建议的重负载,我最终编写自己的session并且session container实现了session per request pattern.另外,我有很多DAOs并且我不愿意为我save method所有的DAOs复制粘贴这个Hibernate写相同的内容GenericDAO(我不能说它是同样的事情,因为当时hibernate不是由jboss拥有)并且做管道工作,并且在压力下,所有变得很快复杂并且在生产中,StaleObjectException和重复数据正确,我我觉得是时候回顾一下我所做的事情,简化它并使其更适合大数据处理.你应该知道的一件事是,一个请求涉及许多DAO.

有石英运行数据库中的一些更新.

尽管我想要更好地调整所有内容,但我没有时间进行必要的研究,而Hibernate则是一种巨大的(学习).

所以就是这样,我想借用你的经验,并提出几个问题,知道要采取什么方向.

问题1:Hibernate生成的uuid足够安全,可以用于线程环境并避免使用StaleObjectException吗?

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

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

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

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

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

Pas*_*ent 14

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

您应该删除所有这些代码并使用Spring/Hibernate API:减少错误,减少维护.

我复制粘贴这个Hibernate GenericDAO(我不能说它是同一个东西,因为当时hibernate不归jboss所有)并且做了管道工作,并且在压力下,所有都变得很快复杂(...)

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

问题1:Hibernate生成的uuid是否足够安全,可以用于线程环境并避免StaleObjectException

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

5.1.4.1.发电机

...

  • uuid

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

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

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

最好的策略是只使用它,sessionFactory.getCurrentSession()总是会给你一个Session当前数据库事务的范围,即"上下文会话".再次引用参考文档:

2.5.上下文会话

大多数使用Hibernate的应用程序都需要某种形式的"上下文"会话,其中给定的会话在给定上下文的范围内有效.但是,在不同的应用程序中,构成上下文的定义通常是不同的; 不同的上下文定义了当前概念的不同范围.使用Hibernate 3.0版之前的应用程序倾向于使用自行开发的基于ThreadLocal的上下文会话,辅助类(如HibernateUtil),或利用第三方框架(如Spring或Pico),它们提供基于代理/拦截的上下文会话.

(......)

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

有关org.hibernate.context.CurrentSessionContext 其合同的详细讨论,请参阅Javadocs以获取 接口.它定义了一个方法,currentSession()实现负责跟踪当前的上下文会话.开箱即用,Hibernate附带了这个界面的三个实现:

  • org.hibernate.context.JTASessionContext:当前会话由JTA事务跟踪和确定范围.此处的处理与旧的仅JTA方法完全相同.有关详细信息,请参阅Javadocs.
  • org.hibernate.context.ThreadLocalSessionContext:当前会话由执行线程跟踪.有关详细信息,请参阅Javadocs.
  • org.hibernate.context.ManagedSessionContext:当前会话由执行线程跟踪.但是,您负责使用此类上的静态方法绑定和取消绑定Session实例:它不会打开,刷新或关闭会话.

(......)

现在没有必要实现自己ThreadLocal的解决方案,不要这样做.

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

好吧,HibernateTemplate不推荐使用,但不推荐使用它,我更喜欢实现无模板的DAO:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

SessionFactory被Spring注入.我建议阅读所以你还应该使用Spring的HibernateTemplate和/或JpaTemplate吗?完整的背景和整个13.3.关于ORM数据访问的Spring文档中的Hibernate.

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

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

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

3.3.JDBC连接

...

以下是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
Run Code Online (Sandbox Code Playgroud)

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