我有下一个问题。当控制器调用服务方法时 @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(..)方法中的注解。。。这个例子很成功(对象已修改)。
为什么会这样?
1条答案
按热度按时间vuktfyat1#
我懂了
save
方法的注解为@Transactional
还有电话findOne
方法也是@Transactional
. 所以在这种情况下,同一个事务被传播到findOne
方法,并将只读行为应用于当前事务。所以它不执行flush,您可以看到实体没有被修改。因此,在这种情况下,应该使用单独的事务进行读写。
findOne
方法可以用下面的注解-