2014-07-12 19 views
2

這是最DAO中使用的典型設置:@Transactional如何影響Hibernate中的當前會話?

@Transactional 
@Repository 
public class DAO { 

    @Autowired 
    SessionFactory sessionFactory; 

    public void save(Entity o) { 
     sessionFactory.getCurrentSession().save(o); 
    } 

    public Entity load(int id) { 
     return (Entity)sessionFactory.getCurrentSession().get(Entity.class, id); 
    } 

} 

我只看到getCurrentSession()叫,沒有openSessionclose

因此,當我從load返回實體時,它不在會話中,無法加載懶惰集合。同樣,保存似乎總是沖洗!

春季的@Transactional註釋是否獨自開啓和關閉會話和交易?

+0

是看看這個答案http://stackoverflow.com/questions/10680364/how-spring-manage-hibernate-session-lifecycle –

+0

@ShadowRay嘿,謝謝。鏈接很好,但不涉及'@ Transactional'。你是否可以描述當你連接sessionFactory時會發生什麼,然後調用DAO的方法? –

回答

4

在春季,在由@Transactional劃定的商業交易與休眠Session之間存在一對一的對應關係。

也就是說,當通過調用@Transactional方法開始業務事務時,會創建hibernate會話(TransactionManager可能會延遲實際創建,直到首次使用會話)。一旦該方法完成,業務事務就會被提交或回滾,從而關閉休眠會話。在你的情況下,這意味着調用一個DAO方法將開始一個新的事務(除非一個事務已經在進行),並且退出DAO方法將會結束它,這會關閉休眠會話,同時也會刷新它,並提交或回退相應的hibernate事務,後者又提交或回滾相應的JDBC事務。

至於這是典型的用途,hibernate文檔稱之爲session-per-operation anti pattern。同樣,Spring參考手冊中的@Transactional的所有示例都放在業務服務方法(或類)上,而不是存儲庫。

2

Spring爲@Transactional註釋的bean提供了交易建議。 Spring事務爲以下六個屬性提供支持,這六個屬性決定事務的行爲

1.isolation,2.no-rollback-for,3.propagation,4.read-only,5.rollback-for,6.timeout 。

@Transactional可以啓動新的事務或可以根據其傳播屬性值加入現有的事務上下文。

@Transactional上下文中,getCurrentSession()方法創建新的會話對象,如果它不存在或返回連接到當前事務的會話。 OpenSession()方法總是創建新的會話。 @Transactional可幫助您擴展Session的範圍。

當執行getCurrentSession()時,會話首次打開,並且在事務結束並且在事務提交之前將其刷新時關閉。

在春天,如果我們在非事務性上下文中使用getCurrentSession(),我們會得到一個異常。

+0

好的,謝謝!所以當我輸入一個方法時,在一個@ Transactional類中,一個事務已經在進行中了嗎?一旦我離開了這個方法,它就承諾了嗎?所以,從Hibernate的角度來看,當我離開這個方法時,這些變化是否會將實體刷新到數據庫,並且實體是否已經分離? –

+0

並非總是如此。它取決於你的傳播模式和隔離級別。例如PROPAGATION_MANDATORY =如果沒有現有的事務正在進行,方法總是以事務開始。通過使用傳播模式,我們可以在一個事務中運行不同的@Transaction方法。 – Bhushan

相關問題