Java SpringBoot中管理并发POST请求的最佳实践

Java SpringBoot中管理并发POST请求的最佳实践,java,spring,rest,post,http-post,Java,Spring,Rest,Post,Http Post,我正在用SpringBoot构建一个REST-API并使用这个控制器 @RestController class EmployeeController { private final EmployeeRepository repository; EmployeeController(EmployeeRepository repository) { this.repository = repository; } @GetMapping("/employees

我正在用SpringBoot构建一个REST-API并使用这个控制器

@RestController
class EmployeeController {

  private final EmployeeRepository repository;

  EmployeeController(EmployeeRepository repository) {
    this.repository = repository;
  }

  @GetMapping("/employees")
  List<Employee> all() {
    return repository.findAll();
  }

  @PostMapping("/employees")
  Employee newEmployee(@RequestBody Employee newEmployee) {
    return repository.save(newEmployee);
  }
@RestController
类EmployeeController{
私人最终雇员存储库;
EmployeeController(EmployeeRepository存储库){
this.repository=存储库;
}
@GetMapping(“/employees”)
列出所有(){
返回repository.findAll();
}
@后映射(“/员工”)
Employee newEmployee(@RequestBody Employee newEmployee){
返回repository.save(newEmployee);
}
我想确保API使用者不能向同一名
员工发送多个并发POST请求。我知道我可以在保存实体之前检查该实体是否已存在于数据库中,但我担心性能会很差。我还注意到,您可以在enti中使用类似
@version
的注释ty,对现有实体的更多保存进行更新


但是,在Spring中,是否还有一种方法或最佳实践可以使用一个潜在的新实体来处理此POST请求?

您希望POST/EMPLOYEE
端点的请求吞吐量是什么?虽然性能很重要,但过早优化几乎总是会导致您的代码比需要的更丑他没有什么收获

按照您的代码目前的状态,多个并发的
POST/employees
请求将以先到先得的方式结束,其中将创建应用程序中具有给定
UNIQUE
约束的第一个用户(希望由基础DBMS强制执行),然后创建所有其他用户(针对同一用户)将由于例如
ConstraintViolationException
(映射到例如
DataIntegrityViolationException
)而失败。从这个角度来看(只要您没有复杂的分布式DBMS设置),数据的一致性仍然是有保证的

当然,缺点是返回的错误消息可能是:

  • 特定于供应商并泄漏底层实现(例如,我们向客户端显示我们正在使用Hibernate)
  • 客户端可能很难解析
  • 如果改为,请将实现更改为以下内容:

    @PostMapping(“/employees”)
    Employee newEmployee(@RequestBody Employee newEmployee){
    核实雇员身份证(新雇员);
    返回repository.save(newEmployee);
    }
    私有void verifyUserDoesNotExist(员工){
    if(repository.exists)(newEmployee){
    抛出new EmployeeAlreadyExistsException(“Employee”+newEmployee.getName()+“已存在”;
    }
    }
    
    然后,您可以更轻松地控制端点和底层流程的控制流,这可能会允许更容易理解的异常处理。这可以通过添加自定义异常来进一步改进,例如,自定义异常也包含一些预定义的
    错误代码
    ,例如
    错误409代码1010名员工已存在

    当然,Spring针对Hibernate的内置异常转换(例如,
    HibernateExceptionTranslator
    )对于您的用例来说可能已经足够好了,甚至可以进行扩展,这个扩展甚至可以推广


    最后,最好的做法是使代码干净、可读和可维护。然后开始添加功能来监控代码。之后,只有在性能有问题时,才可以对其进行优化。

    检查员工是否存在并不会像您提到的那样保存您。您必须添加速率限制来处理请求甚至在到达db之前。或者你必须使用一个版本的锁定。好了,没有其他方法了