我们有一个如下所示的控制器:
@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);
}
答案 0 :(得分:1)
您的代码中没有线程之间共享的任何状态。 除非您的存储库不返回某些可以在少数线程之间共享的缓存对象。
如果存储库在每个findById
方法调用中都执行DB调用并创建了新的Sample
对象,则该对象仅对当前线程可见。
Why are local variables thread safe in Java
但是您有Transaction Isolation问题,因为服务的方法updateSample
在事务范围之外执行,并且DB中的数据可以由findById
和save
之间的另一个线程或进程更改。
答案 1 :(得分:0)
好吧,让我们深入探讨如何处理您的示例:
(tomcat, undertown, jetty, others)
管理一个线程池,每个请求都由一个安全的线程处理。Controller
时,将创建一个线程安全的线程,并一直保留到控制器返回响应以完成请求为止。因此,请求在Service
中执行了一些逻辑,并且调用Repository
将在线程安全中。 (Gatling, JMeter, or other)
对并发请求测试此简单代码,并且不会出现任何问题,因为应用程序服务器创建了一个线程池来管理并发处理的线程安全,并且因此,他们使用的所有共享资源(服务,存储库等)必须确保线程安全。