2015-10-03 294 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