簡體   English   中英

在Java Spring中調試事務注釋

[英]debugging Transactional annotation in Java Spring

如下所示更新現有代碼:

@Override
@Transactional
public void update(SomeObject someObj) throws BusinessServiceException {
    ...
    someObjectRepository1.update(someObj);
    someObjectRepository2.create(someObj);

    //New code below:
    someObjectRelatedService.doStuff(someObj);  // <--new code
    //Throws error, object does not exist in someObjectRepository2
}

這里的問題是someObjectRelatedService.doStuff需要someObjectRepository2的最新和最新版本-但是事務注釋阻止了這種情況的發生,它將在方法完全運行后更新存儲庫。 我能夠通過使用調試器並在兩者之間運行數據庫調用來進行驗證。

解決這種情況的最佳方法是什么? 是否僅在事務方法外部提取someObjectRelatedService調用?

本質上,您需要移動事務的邊界。 雖然可以手動刷新事務,但我不建議這樣做。

如果SomeObjectRepository2#create(...)的語義允許,最簡單的解決方法是使用@Transactional(isolation = Propagation.REQUIRES_NEW)注釋此方法。

如果這不可能,我建議進行以下較小的重新設計。 首先,我們使用一個方法創建一個新類,該方法應執行與所需數據相關的代碼:

@Component
public class NewClass {
    final SomeObjectRepository2 someObjectRepository2;

    @Autowired
    public NewClass(final SomeObjectRepository2 someObjectRepository2) {
        this.someObjectRepository2 = someObjectRepository2;
    }

    @Transactional(isolation = Propagation.REQUIRES_NEW) // enforces new transaction
    public WhateverNeedsToBereturned newMethod(WhateverType someObject) {
        return someObjectRepository2.create(someObj);
    }
}

然后,我們重寫現有代碼以使用新類:

@Override
@Transactional
public void update(SomeObject someObj) throws BusinessServiceException {
    ...
    someObjectRepository1.update(someObj);
    newClassInstance.newMethod(someObj);

    //New code below:
    someObjectRelatedService.doStuff(someObj); 
    //Throws error, object does not exist in someObjectRepository2
}

請注意,您必須創建一個新類才能使其正常工作。 通過this -reference進行的方法調用不被代理,因此@Transactional注釋不生效。

還要注意, newClassInstance相同的原因,必須通過DI容器注入newClassInstance

暫無
暫無

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

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