Spring @Transactional仅在调用者也是@Transactional

时间:2016-03-26 15:51:09

标签: java spring spring-boot spring-transactions

我很想知道为什么在尝试使用@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),它也能正常工作。

我从春天开始阅读有关交易的文件,但我仍然不明白为什么它不起作用。我检查了debuger,userService是Spring Proxy的形式。

有人可以帮我解释一下吗?

1 个答案:

答案 0 :(得分:0)

问题是您的操作不受该服务方法的约束:在这两种情况下,您都要在调用方法中从存储库中检索对象。您的事务必须涵盖整个数据库操作集合。

至于你的控制器实际 工作的原因,我不能仅仅通过这些信息说出来,但我猜你正在使用OpenEntityManagerInView和获得免费的交易边界。