spring引导@调用@transactional(readonly=true)方法的事务性方法

bxgwgixi  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(496)

我有下一个问题。当控制器调用服务方法时 @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;
    }   
}

本例不更新对象属性。但如果我去掉 @Transactional save(..)方法中的注解。。。这个例子很成功(对象已修改)。
为什么会这样?

vuktfyat

vuktfyat1#

我懂了 save 方法的注解为 @Transactional 还有电话 findOne 方法也是 @Transactional . 所以在这种情况下,同一个事务被传播到 findOne 方法,并将只读行为应用于当前事务。所以它不执行flush,您可以看到实体没有被修改。
因此,在这种情况下,应该使用单独的事务进行读写。 findOne 方法可以用下面的注解-

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

相关问题