2014-04-29 48 views
0

在我的理解中,newPrint方法在下面的代碼中應該創建一個新的事務,但顯然它會打印出與oldPrint方法中使用的相同的事務狀態對象。我從另一個班級打電話給老朋友。是否因爲使用this來調用newPrint?如果是,那麼何時會創建新的交易?如果我從另一個班級調用兩種方法,則無論如何將創建兩個單獨的事務,因爲在班級級別使用@TransactionalSpring Propagation.REQUIRES_NEW

@Transactional 
public class Unsubcriber { 


    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
    public void newPrint() { 
     System.out.println(TransactionAspectSupport.currentTransactionStatus()); 
    } 

    public void oldPrint() { 

     System.out.println(TransactionAspectSupport.currentTransactionStatus()); 
     newPrint(); 
    } 

輸出:

o[email protected]3bacd0e7 
o[email protected]3bacd0e7 

會是什麼情景時Propagation.REQUIRES_NEW會的工作?

+0

裏面oldPrint,你的意思'('的newPrint),而不是'打印()'? – geoand

+0

@geoand我的壞,只是編輯我的問題。謝謝! – Abidi

+0

檢查我的答案:) – geoand

回答

0

你所看到的是關於Spring AOP的類錯誤觀念。

由於newPrint()正在從同一個類中的方法調用,並沒有建議被觸發,此處不再處理的事務發生。

假如你調用的方法newPrint()類外,主叫方是否沒有參與交易的新交易將被創建。

由於您已在課程上使用@Transactional,因此每種方法的默認設置爲@Transactional,這就是您實際上有交易的原因。

看看關於AOP如何在春天有個詳細的討論了Spring參考文檔的this部分。

共黑客讓你的代碼工作像你期望會是以下幾點:

((Unsubcriber) AopContext.currentProxy()).newPrint(); 

該解決方案在各個地方提到的其中之一是this SO崗位。

+0

我明白了,問題是我該如何利用Propagation.REQUIRES_NEW? – Abidi

+0

檢查我更新的答案 – geoand

0

從(使用this)在類中調用的方法意味着它不會通過包含Spring的代理對象中的交易初始化。由於this關鍵字是指向原始對象實例的指針,而不是事務感知的增強型Spring對象。如預期的情況下,如

的說明,將工作:

object1.oldPrint(); 
object1.newPrint(); 
1

假設geoand的編輯澄清是真實的,回答你的問題是Spring使用AOP代理申請的交易限制。所以,這將適用於來自外部的未取消訂閱者的調用,然後可以攔截該訂閱者,並且可以應用事務邊界。如果你是從課堂內部調用它,如你所說,使用'this',那麼沒有代理可以完成,因此你的@Transactional不會發揮作用。

1

這裏有提

1. @事務註釋只對公共方法的工作@Transactional價值的一些規則。如果你有一個使用這個註解的私有或受保護的方法,Spring AOP沒有(容易的)方法來查看註釋。它不會發瘋嘗試 找到它們,所以確保所有註釋的方法都是公開的。

2.只有在通過Spring代理正確註釋(參見上文)方法時纔會創建交易邊界。這意味着 您需要直接通過@Autowired bean調用您的註釋方法,否則事務將永遠不會啓動。如果您調用 @Autowired bean的未註釋方法,該方法本身稱爲已註釋的公開 方法您的註釋是IGNORED。這是因爲 Spring AOP僅在首次輸入 @Autowired代碼時才檢查註釋。

來源 - http://blog.timmattison.com/archives/2012/04/19/tips-for-debugging-springs-transactional-annotation/

相關問題