2015-10-03 295 views
3

所以,我在Spring中使用Hibernate DAO。我的DAO将由IOC容器的ApplicationContext构建,并且SessionFactory将由容器注入(LocalSessionFactoryBean)。休眠和线程安全:注入的SessionFactory线程安全吗?

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

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

问题是,同步SessionFactory需要同步所有对它的调用。因此,我在下面放入的insertPortfolio()方法也需要同步,这样就会使数据库具有可用连接池的目的失败,因为访问一次只限于一个线程。

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

private SessionFactory sessionFactory; 

public HibernatePortfolioDao() {} 

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

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

回答

0

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

0

hibernate中的SessionFactory是线程安全的。你应该使用单例机制来实现它,因为它资源枯竭。

6

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

你所关心的是返回sessionFactory.getCurrentSession()这是绑定到当前线程HibernateTransactionManager