簡體   English   中英

Spring Propagation.REQUIRES_NEW

[英]Spring Propagation.REQUIRES_NEW

在我的理解中,以下代碼中的newPrint方法應該創建一個新事務,但顯然它打印出與oldPrint方法中使用的相同的事務狀態對象。 我從另一個班級打電話給oldPrint。 是因為使用this來調用newPrint嗎? 如果是,那么什么時候會創建新的交易? 如果我從另一個類調用這兩個方法,則無論如何都會創建兩個單獨的事務,因為在類級別使用了@Transactional

@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();
    }

輸出:

org.springframework.transaction.support.DefaultTransactionStatus@3bacd0e7
org.springframework.transaction.support.DefaultTransactionStatus@3bacd0e7

Propagation.REQUIRES_NEW工作時會出現什么情況?

假設geoand的編輯說明是正確的,那么您的問題的答案是Spring使用AOP代理來應用事務限制。 因此,當來自外部的調用進入您的Unsubscriber時,這將會起作用,然后可以截取它並且可以應用事務邊界。 如果你是在課堂上調用它,正如你所說,使用'this',那么就沒有代理可以完成,因此你的@Transactional不會發揮作用。

這里有一些值得一提的@Transactional規則

1. @ Transactional注釋僅適用於公共方法。 如果你有一個帶有這個注釋的私有或受保護的方法,那么Spring AOP沒有(簡單的)方法來查看注釋。 嘗試找到它們並不瘋狂,因此請確保所有帶注釋的方法都是公開的。

2.只有在通過Spring代理調用正確注釋(見上文)方法時才會創建事務邊界。 這意味着您需要直接通過@Autowired bean調用帶注釋的方法,否則事務將永遠不會啟動。 如果在未注釋的@Autowired bean上調用一個方法,該方法本身會調用一個注釋的公共方法,那么您的注釋就會被忽略。 這是因為Spring AOP僅在首次輸入@Autowired代碼時檢查注釋。

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

你所看到的是對Spring AOP的一種誤解。

由於newPrint()是從同一個類內的方法調用的,因此不會觸發任何建議,因此不會對事務進行處理。

如果您在類外部調用newPrint()方法,則無論調用者是否已參與事務,都將創建一個新事務。

由於您在類上使用了@Transactional ,因此每個方法都是默認的@Transactional設置,這就是您實際擁有事務的原因。

看一下Spring參考文檔的這一部分,詳細討論AOP如何在Spring中運行。

讓您的代碼按預期運行的完全破解如下:

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

這個 SO帖子中提到了這個解決方案。

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

注釋將在以下場景中按預期工作:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM