因此,我在Spring中使用了Hibernate DAO。我的DAO将由ApplicationContext IOC容器构造,而SessionFactory将由容器(LocalSessionFactoryBean)注入。
现在,这个DAO将是一个单例,用于我的程序中的所有CRUD操作,后面有一个数据库连接池。我关心的是sessionFactory字段的线程安全性。
我对线程安全的理解是,在多线程环境中,所有状态字段都需要受到保护。现在,这个类的用法是,Spring将在创建bean时设置SessionFactory,并且在创建bean之后不会更改该工厂。这意味着从技术上讲,它可以在多线程环境中安全地运行,但我觉得这是一个非常危险的做法,只是假设setter方法不会再次被调用。
问题是,同步SessionFactory也需要同步对它的所有调用。因此,我在下面放入的insertPortfolio()方法也需要同步,这与拥有数据库可用连接池的目的背道而驰,因为一次只能访问一个线程。
我想我能想到的最好的解决方案是将这个从setter注入改为构造器注入,并将SessionFactory字段设为final。但我正在尝试理解这里涉及的更广泛的问题,这样我就可以在未来使用spring做出良好的多线程安全决策。
private SessionFactory sessionFactory;
public HibernatePortfolioDao() {}
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
@Override
public void insertPortfolio(PortfolioModel portfolioModel) {
sessionFactory.getCurrentSession().save(portfolioModel);
}发布于 2016-03-24 15:24:53
SessionFactory是线程安全的,并且在应用程序引导期间只初始化一次。因为您使用的是Spring,所以SessionFactory由LocalSessionFactoryBean表示。
您所关心的是由sessionFactory.getCurrentSession()返回的Seesion,它由HibernateTransactionManager绑定到当前线程。
发布于 2015-10-04 03:48:33
一个很好的起点就是类本身:http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/SessionFactory.html
SessionFactory的内部状态是不可变的。一旦它被创建,这个内部状态就被设置。此内部状态包括有关对象/关系映射的所有元数据。
这使得它可以由多个线程共享,而不必担心同步问题。
发布于 2016-03-23 17:15:57
实现SessionFactory的框架必须使它们的SessionFactories线程安全和并发。如果您使用的是一个好的框架,那么可以认为注入的sessionFactory是线程安全的。您不必担心会话工厂实现,因为文档要求实现是线程安全的。从会话工厂获得sessions是针对每个会话/事务的,不必是线程安全的。
https://stackoverflow.com/questions/32926548
复制相似问题