所以,我在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);
}
答案 0 :(得分:6)
SessionFactory
是线程安全的,并且在应用程序引导期间只初始化一次。由于您使用的是Spring,SessionFactory
由LocalSessionFactoryBean
表示。
您所担心的是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是线程安全的。您应该使用单一机制实现它,因为它耗尽了资源。