简体   繁体   English

Spring @Transactional仅在调用者也是@Transactional时才有效

[英]Spring @Transactional only works if caller is also @Transactional

I am strugelling to understand why are my updates not commited when i try to use a @Scheduled method. 我很想知道为什么当我尝试使用@Scheduled方法时,我的更新没有被提交。
This is a simplification of my scenario: 这是我的情况的简化:

@Service
public class UserService {

    @Transactional
    public void updateUser(User user){
        user.setName("Doe");
    }
}

This service is called from two locations: 此服务从两个位置调用:

@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);
    }
}

and a service that use a @Scheduled method: 和使用@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);
    }
}

My problem is that when I try to update the user through the InternalService the user never gets updated - but it is getting updated perfectly fine through the RestController. 我的问题是,当我尝试通过InternalService更新用户时,用户永远不会更新 - 但它通过RestController完全更新。 When I add the @Transactional annotation for the scheduled method (even with readOnly = true) it works. 当我为预定方法添加@Transactional注释时(即使readOnly = true),它也能正常工作。

I read the documentation from spring regarding transactions but i still don`t understand why is it not working. 我从春季开始阅读有关交易的文档,但我仍然不明白为什么它不起作用。 I checked with the debuger and userService is in the form of a Spring Proxy. 我检查了debuger,userService是Spring Proxy的形式。

Can someone help me with an explanation for this? 有人可以帮我解释一下吗?

The problem is that your operation isn't constrained to that service method: In both cases, you're retrieving the object from the repository in the calling method. 问题在于您的操作不限于该服务方法:在两种情况下,您都是从调用方法中的存储库中检索对象。 Your transaction has to cover the entire collection of database operations. 您的事务必须涵盖整个数据库操作集合。

As to why your controller actually is working, I can't say for sure with just this information, but I'd guess that you are using OpenEntityManagerInView and getting a transactional boundary for free. 至于为什么您的控制器实际上工作,我不能OpenEntityManagerInView此信息确定确切的位置,但是我猜您正在使用OpenEntityManagerInView并免费获取事务边界。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM