我正在查看一些现有代码,并希望了解Spring的@Transactional注释在以下场景中会发生什么?请考虑以下示例:
POST请求命中使用@Transactional注释的@Controller:
@ResponseBody
@Transactional
@RequestMapping(value="/send", method=RequestMethod.POST)
public void send(@RequestBody Response response) {
try {
DBItem updatedDbItem = repository.updateResponse(response);
if (updatedDbItem == null){
//some logging
}
} catch(Exception ex) {
//some logging
}
}
控制器调用非@transactional存储库方法,该方法设置一个值,然后再调用另一个@Transactional方法:
@Override
public DBItem updateResponse(Response response) {
try {
DBItem dBItem = findResponseById(response.getKey());
if (dBItem != null){
dBItem.setSomeField(response.getValue());
return updateDataBaseItem(response);
}
} catch (Exception ex) {
//some logging
}
return null;
}
以下updateDataBaseItem()方法很常见,并且从其他非事务方法以及上述方法调用:
@Transactional
@Override
public DBItem updateDataBaseItem(Response response){
try {
DBItem dBItem = em.merge(response);
return dBItem;
} catch (Exception ex) {
//some logging
}
return null;
}
答案 0 :(得分:0)
send()
=> spring使用默认参数检测@transaction
实际传播设置是必需的,弹簧加入存在的事务或如果没有则创建新的。repository.updateResponse(..)
=>没有事务参数在同一事务中执行的方法已经存在updateDataBaseItem(..)
=>在同一个存储库中调用该方法时,spring将无法识别@Transaction注释因为使用代理模式,所以此方法将在同一事务中执行目标对象中的一个方法,调用目标的另一个方法 对象,即使在运行时也不会导致实际的事务 调用的方法用@Transactional
标记