【问题标题】:How to make Spring boot post api Idempotent如何使 Spring Boot post api 幂等
【发布时间】:2020-11-10 01:39:54
【问题描述】:

我在我的 Spring 启动应用程序中使用 Spring Data JPA 创建了简单的 CRUD api。我在控制器中的 Post 方法如下所示:-

@RequestMapping(value = "/article", method = RequestMethod.POST, produces = "application/json")
public Article createArticle(@RequestBody Article article) {
    return service.createArticle(article);
}

服务方法如下:-

@Override
public Article createArticle(Article articleModel) {
    return repository.save(articleModel);
}

我的 JsonPayload 如下所示:

{
   "article_nm":"A1",
   "article_identifier":"unique identifier"
}

现在我想将我的 POST 请求设为幂等,这样即使我再次获得具有相同 article_identifier 的 json 有效负载,它也不会在 DB 中创建记录。

我无法在数据库中进行任何方案/约束更改,article_identifier 字段也不是表中的主键。

我知道首先我可以签入数据库并返回已保存的记录作为响应,如果它已经存在,但是如果多个请求(原始请求和重复请求)同时出现,两者都会签入数据库并且找不到任何记录使用该标识符并将创建 2 条记录(每条记录)。此外,由于它是一个分布式应用程序,我如何保持多个数据库事务之间的一致性。

我怎样才能使用一些锁定机制,这样就不会有 2 条具有相同 article_identifier 的记录。有人可以建议一些参考如何在 Spring boot 中实现它吗?

【问题讨论】:

  • article_identifier是数据库的主键吗?
  • @kavithakaran 不,不是。我已经在我的帖子中提到过。
  • 与问题无关,但请注意,在 REST 架构中,GETPUTDELETE 是幂等的。使用POST 这样做可能会使 API 使用者感到困惑。

标签: spring-boot post locking idempotent sql-server-2019


【解决方案1】:

这种情况下需要幂等性来解决回发(或双发请求)。最简单的方法是在服务级别检查是否存在具有给定信息的帖子(如您所指出的)。您可以为此使用repository.exists() 变体。

我了解,首先我可以签入数据库并返回已保存的记录作为响应(如果已存在)

至于

如果多个请求(原始请求和重复请求)同时出现,则两者都将检查数据库并且不会找到具有该标识符的任何记录,并将创建 2 条记录(每个一条)

如果是单个数据库,则需要将事务彼此隔离(我知道您说不是,但我试图解释我的推理,请耐心等待)。因为那个弹簧有以下注释:@Transactional(isolation = Isolation.SERIALIZABLE)。虽然在这种情况下@Transactional(isolation = Isolation.REPEATABLE_READ) 就足够了。

由于它是一个分布式应用程序,我如何在多个数据库事务之间保持一致性。

它是如何分布的?您首先需要考虑数据库。是主从 mysql / postgress / mongodb 吗?这是一些奇怪的全球分布式系统吗?假设它是传统的主从设置,那么写入事务将由主控处理(据我所知,属于该事务的所有选择也将在那里)所以应该没有问题。但是,只有提供更多细节才能真正给出答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-09
    • 2023-01-28
    • 2019-12-28
    • 2016-02-15
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多