2011-11-24 124 views
1

我有我的項目代碼與此類似通過春季註釋進行交易 - 只讀還是不行?

@Transactional(readOnly = true) 
public void tt() { 
    dd(); 
} 

@Transactional() 
public void dd() { 
    gg(); 
} 

@Transactional(readOnly = true) 
public void gg() { 

} 

功能的DD都是由其他只讀交易功能,而不是隻讀功能使用。假設事務應該從tt執行到gg - dd中的操作將是隻讀事務或不是?

回答

3

Spring的AbstractPlatformTransactionManager有一個名爲validateExistingTransaction控制這種行爲特性。 Javadoc中指出:

參與現有事務時(例如,用PROPAGATION_REQUIRES或PROPAGATION_SUPPORTS遇到的現有事務),該外事務的特徵將應用於甚至到內事務範圍。驗證將檢測內部事務定義中不兼容的隔離級別和只讀設置,並相應地通過拋出相應的異常來拒絕參與。

由於春季@Transactional註釋默認傳播是REQUIRED和默認的驗證策略是假的,我希望Spring使用現有的以只讀模式tt方法調用創建的事務。

如果你想有一個只讀事務,那麼你有註釋的方法:

@Transactional(propagation=Propagation.REQUIRES_NEW, readOnly=true) 
3

使用@Transactional(readoOnly = true)如果您正在執行get/select並且沒有進行任何更改,這意味着不會應用鎖(這更有效)。

對於更新/插入/刪除/保存/合併我使用(需要鎖時):

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
5

在這個特殊的例子,你的問題是沒有實際意義。

dd()tt()的調用將不會通過代理邊界,因此沒有交易建議將應用於dd()(因爲它是在同一實例內的調用)。與撥打電話gg()dd()一樣。因此,只有從外部撥打tt()的電話實際上是交易建議的(在您的情況下爲readOnly=true),並且這將是整個呼叫鏈中將使用的交易。

但是,在一般情況下,閱讀由@melihcelik暗示的文檔 - 它解釋了行爲。