Spring @Transactional 只有在调用者也是@Transactional 时才有效
Spring @Transactional only works if caller is also @Transactional
我很难理解为什么当我尝试使用 @Scheduled
方法时我的更新没有提交。
这是我的场景的简化:
@Service
public class UserService {
@Transactional
public void updateUser(User user){
user.setName("Doe");
}
}
从两个位置调用此服务:
@RestController
@RequestMapping(value = "/users")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public void getAvailableIssuers(@PathVariable("id") String id){
User user = userRepository.findOne(id);
userService.updateUser(user);
}
}
和使用 @Scheduled
方法的服务:
@Component
class InternalService {
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@Scheduled(fixedRate=1000)
public void updateUser(){
User user = userRepository.findOne(1L);
userService.updateUser(user);
}
}
我的问题是,当我尝试通过 InternalService
更新用户时,用户永远不会更新 - 但它通过 RestController 更新得非常好。当我为预定方法添加 @Transactional
注释时(即使使用 readOnly = true),它也有效。
我阅读了 spring 中有关交易的文档,但我仍然不明白为什么它不起作用。我检查了调试器,userService 的形式是 Spring 代理。
谁能帮我解释一下?
问题是您的操作不限于该服务方法:在这两种情况下,您都是在调用方法中从存储库中检索对象。您的事务必须涵盖整个数据库操作集合。
至于为什么您的控制器实际上 在 工作,仅凭这些信息我不能确定,但我猜您正在使用 OpenEntityManagerInView
并免费获得交易边界。
我很难理解为什么当我尝试使用 @Scheduled
方法时我的更新没有提交。
这是我的场景的简化:
@Service
public class UserService {
@Transactional
public void updateUser(User user){
user.setName("Doe");
}
}
从两个位置调用此服务:
@RestController
@RequestMapping(value = "/users")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public void getAvailableIssuers(@PathVariable("id") String id){
User user = userRepository.findOne(id);
userService.updateUser(user);
}
}
和使用 @Scheduled
方法的服务:
@Component
class InternalService {
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@Scheduled(fixedRate=1000)
public void updateUser(){
User user = userRepository.findOne(1L);
userService.updateUser(user);
}
}
我的问题是,当我尝试通过 InternalService
更新用户时,用户永远不会更新 - 但它通过 RestController 更新得非常好。当我为预定方法添加 @Transactional
注释时(即使使用 readOnly = true),它也有效。
我阅读了 spring 中有关交易的文档,但我仍然不明白为什么它不起作用。我检查了调试器,userService 的形式是 Spring 代理。
谁能帮我解释一下?
问题是您的操作不限于该服务方法:在这两种情况下,您都是在调用方法中从存储库中检索对象。您的事务必须涵盖整个数据库操作集合。
至于为什么您的控制器实际上 在 工作,仅凭这些信息我不能确定,但我猜您正在使用 OpenEntityManagerInView
并免费获得交易边界。