弹簧套@事务性方法调用@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;
}   
}

此示例不更新对象属性。但是如果我删除save(..(方法中的@Transactional注释。。。这个例子很成功!(对象已修改(。

为什么会发生这种情况?

我看到save方法用@Transactional进行了注释,并调用了findOne方法,该方法也是@Transactional。因此,在这种情况下,相同的事务被传播到findOne方法,并且它将只读行为应用于当前事务。所以它不执行Flush,并且您可以看到实体并没有被修改。

因此,在这种情况下,您应该使用一个单独的事务进行读取和写入。

findOne方法可以用以下进行注释

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

相关内容

最新更新