Hibernate&线程安全:注入的SessionFactory线程是否安全?

时间:2015-10-03 19:22:10

标签: java multithreading spring hibernate

所以,我在Spring中使用了Hibernate DAO。我的DAO将由ApplicationContext IOC容器构建,SessionFactory将由容器(LocalSessionFactoryBean)注入。

现在,这个DAO将成为一个单例,用于我程序中的所有CRUD操作,后面有一个数据库连接池。我关心的是sessionFactory字段的线程安全性。

我对线程安全的理解是所有状态字段都需要在多线程环境中保护。现在,使用这个类将是Spring将在创建bean时设置SessionFactory,之后该工厂不会被更改。这意味着技术上它可以在多线程环境中安全地运行,但我觉得这是一种非常冒险的做法,只是假设不会再次调用setter方法。

问题是,同步SessionFactory将要求同步所有调用。所以我在下面输入的insertPortfolio()方法也需要同步,这样就失去了与数据库建立可用连接池的目的,因为一次只能访问一个线程。

我想我能想到的最佳解决方案是将其从setter注入更改为构造函数注入,并使SessionFactory字段成为final。但是我试图了解这里涉及的更广泛的问题,所以我可以在未来春天做出很好的多线程安全决策。

private SessionFactory sessionFactory;

public HibernatePortfolioDao() {}

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

@Override
public void insertPortfolio(PortfolioModel portfolioModel) {
    sessionFactory.getCurrentSession().save(portfolioModel);
}

4 个答案:

答案 0 :(得分:6)

SessionFactory是线程安全的,并且在应用程序引导期间只初始化一次。由于您使用的是Spring,SessionFactoryLocalSessionFactoryBean表示。

您所担心的是Seesion返回的sessionFactory.getCurrentSession()正确绑定到HibernateTransactionManager的当前主题。

答案 1 :(得分:0)

开始寻找的好地方是班级本身:http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/SessionFactory.html

  

SessionFactory的内部状态是不可变的。创建后,将设置此内部状态。此内部状态包括有关对象/关系映射的所有元数据。

这允许它由多个线程共享,而不必担心同步它。

答案 2 :(得分:0)

实现SessionFactory的框架必须使其SessionFactories线程安全且并发。如果您使用的是良好的框架,那么注入的sessionFactory可以被认为是线程安全的。您不必担心会话工厂实现,因为文档要求实现是线程安全的。 您从会话工厂获得的sessions是每个会话/事务,并且不必是线程安全的。

答案 3 :(得分:0)

hibernate中的SessionFactory是线程安全的。您应该使用单一机制实现它,因为它耗尽了资源。