簡體   English   中英

彈簧靴。 @Transactional 方法調用 @Transactional(readonly=true) 方法

[英]Spring Boot. @Transactional method calling a @Transactional(readonly=true) method

我有下一個問題。 當控制器調用帶有@Transactional注釋的服務方法並且該方法調用@Transactional(readonly=true)方法時,對象中的更改不會保存在數據庫中。 我不知道為什么。 我認為第一種方法開始“讀寫”事務,而第二種方法使用相同的事務。

例子 :


/** Controller class **/

@RestController
@RequestMapping("/path1")
public class MyObjectRestController {

    ... 

    @Autowired
    MyObjectService myObjectService;

    @PostMapping(value = "/path2")
    @ResponseStatus(HttpStatus.CREATED) 
    public void save(@RequestBody MyObject myObject) {
        myObjectService.save(myObject);
    }
    
    ...
}
/** Service class **/

public interface MyObjectService {
    public MyObject save(MyObject myObject);
    public MyObject findOne(long id);
}
/** Service implementation class **/

@Service
public class MyObjectServiceImpl implements MyObjectService {

    /**
     * Save Object
     */
    @Override
    @Transactional  
    public Object save(Object newObject) {

        Object myObject = this.findOne(newObject.getId());
        
        // Modify Object
        myObject.setAttribute1(...)
        myObject.setAttribute2(...)
        
        // Save Object (using Repository)
        return MyObjectDao.save(myObject);
    }

    /**
     * Get Object by Id 
     */
    @Override
    @Transactional(readOnly = true)
    public MyObject findOne(long id) {
        Optional<MyObject> myObject = MyObjectDao.findById(id);
        return myObject.isPresent() ? myObject.get() : null;
    }   
}

此示例不更新對象屬性。 但是如果我刪除了 save(..) 方法中的@Transactional注釋……這個例子成功了! (對象被修改)。

為什么會這樣?

我看到save方法用@Transactional注釋並調用findOne方法,該方法也是@Transactional 因此,在這種情況下,相同的事務被傳播到findOne方法,並將只讀行為應用於當前事務。 因此它不執行 Flush 並且你看到實體沒有被修改。

因此,在這種情況下,您應該使用單獨的事務進行讀取和寫入。

findOne方法可以用下面的注釋 -

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

暫無
暫無

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

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