微服务架构中常用的实现幂等性的方式总结

微服务架构中常用的实现幂等性的方式总结

薛定谔的汪

幂等性的定义

幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多点点击或多次请求产生副作用。

举例:用户购买商品支付,支付扣款成功,但是返回结果时网络异常,这时候钱其实已经扣了,用户以为支付失败了,再次点击支付,会进行第二次扣款,返回结果成功,用户查询产生了两条扣款记录,多扣钱了,这就是非幂等。

幂等性的范围

在数据访问层,要求幂等性的往往是对数据写入时。

insert

  • 需要做幂等性

delete

  • 重复删除操作天然是幂等的

update

  • 直接更新某个值的,不需要作幂等
  • 累加等计算操作的更新,需要作幂等

幂等性解决方案

解决幂等性没有最优的,只有最合适的,根据自己的业务自己选型

insert 幂等

  1. 数据库增加唯一字段

    • 优点:实现方式简单方便
    • 缺点:影响数据库性能,尤其是在数据频繁更新的场景,唯一索引比普通索引在写时开销还要大很多,而且还需要专门对 “duplicate key” 异常处理。
  2. 细粒度分布式锁 + select +insert

    在操作时,先加一个细粒度的分布式锁,再去查询数据是否存在,不存在再 insert

    • 优点:性能影响较少,使用的是细粒度锁,所以只有重复提交记录时才会阻塞
    • 缺点:写操作会增加一次select开销,实现难度相对较大因为需要分布式细粒度锁,而且这个锁的时间需要根据业务场景去确定。

update 幂等

  1. update 常用的手段是 版本号控制

  • 表里添加 version 字段

    1
    alter table test_table add version int default 0;
  • 然后更新的时候通过这个version来判断是否为过期无效操作,这是乐观锁的一种思路

    1
    2
    select * from tablename where condition=#{condition}  -- 查询出 version
    update test_table set age=age+1, version=version+1 where version=xx

    为了避免失败,一般还要有重试机制

  1. 有限状态机幂等

    业务单据上有个状态,状态在不同的情况下会发生变更,一般情况下是有限状态机,如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等。

    比如订单新建状态为 0,付款失败为 9,付款成功为 10,在做状态机更新时可以这样:

    1
    update `order` set status=#{status} where id=#{id} and status<#{status}
  2. select for update 不推荐用。

  • Title: 微服务架构中常用的实现幂等性的方式总结
  • Author: 薛定谔的汪
  • Created at : 2019-06-04 19:44:48
  • Updated at : 2023-11-17 19:37:37
  • Link: https://www.zhengyk.cn/2019/06/04/java/idempotence/
  • License: This work is licensed under CC BY-NC-SA 4.0.
On this page
微服务架构中常用的实现幂等性的方式总结