java - 弹簧靴。@Transactional 方法调用 @Transactional(readonly=true) 方法
问题描述
我有下一个问题。当控制器调用带有@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(..) 方法中的注释......这个例子成功了!(对象被修改)。
为什么会这样?
解决方案
我看到save
方法被注释@Transactional
并调用findOne
方法也是@Transactional
. 因此,在这种情况下,相同的事务被传播到findOne
方法,并将只读行为应用于当前事务。因此它不执行刷新,你会看到实体没有被修改。
因此,在这种情况下,您应该使用单独的事务进行读取和写入。
findOne
方法可以用以下注释 -
@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
推荐阅读
- bash - 在 dockerfile 中的 if 语句中运行 npm 命令
- android - 在带有操作栏的活动中使用时,片段未完全显示
- excel - 在另一个工作表中查找
- node.js - 如何停止 webpack 用 github repo 覆盖现有文件/覆盖更改?
- python - 条件更新字典
- php - 图像处理 - 显示特殊字符,但我得到了想要的结果
- python - Apply a custom function row by row with break
- python - Simple autoencoder keeping constant tensor as predict in keras
- react-native - 如何让文本在屏幕上排成一行
- postgresql - 添加列但保留特定 ID