我们有一个如下所示的 Controller :
@RestController()
public class TestController {
@Autowired
TestService testService;
....
// Update request
@PutMapping("/update")
public ResponseEntity<Sample> updateApi(@PathVariable(value = "id") Long id,
@Valid @RequestBody Sample sampleDetails) {
return new ResponseEntity<Sample>(testService.updateSample(id, sampleDetails), HttpStatus.OK);
}
....
服务类(依赖于 JPA 存储库)如下所示:
@Service
public class TestService {
@Autowired
TestRepository testRepository;
// update sample
public Api updateSample(long sampleId, Sample details) {
// Get object to be updated
Sample sample = apiRepository.findById(sampleId);
// Update required fields
sample.setName(details.getName());
sample.setBody(details.getBody());
return apiRepository.save(api);
}
- 在上述服务(TestService)中,对 jpa 存储库的 setName 和 setBody 方法调用:这些步骤是否保持状态(即不是无状态),并且在处理并发请求时可能会导致问题。或者我们是否需要将此服务(或服务中的 updateSample 方法)的范围设置为“Web 感知的 Spring ApplicationContext”
- 与第 1 点类似,此行:“Sample sample = apiRepository.findById(sampleId);”,此行是线程安全的还是在处理并发请求时会导致问题。
最佳答案
您的代码中的线程之间没有共享任何状态。 除非您的存储库不返回一些可以在几个线程之间共享的缓存对象。
如果存储库为每个 findById
方法调用执行数据库调用并创建新的 Sample
对象,则该对象仅对当前线程可见。
Why are local variables thread safe in Java
但是你有Transaction Isolation问题是因为服务的方法 updateSample
执行超出了事务范围,并且 DB 中的数据可以被 findById
和 save
之间的另一个线程或进程更改。
关于java - Spring @Service 对 @PutMapping 并发请求的线程安全问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54364037/