# java多线程并发之接口幂等性设计

# 业务场景

假设你有一个系统,他有一个接口,这个接口接受请求的时候假设会在数据库里插入一条数据,正常情况下一个用户对这个接口发起一次请求应该就只有一条数据,结果可能某一天你会发现这个用户通过这个接口插入了多条数据。

# 初版防重代码

就是会有代码判断一下,当前你要写入的这条数据是否存在,如果他要是不存在的话,就会进行插入,但是如果他存在的话就不会允许你重复插入的。

这个在高并发重试的时候会出现问题,一瞬间发起两次请求参数完全相同的请求。都是第一次都没查询到然后一块存入了

1648175745829.png

# 解法1,数据库幂等(加唯一索引)

数据库层面就会阻止你插入,唯一索引会确保这一点,你重复插入会抛出异常

缺点:因为有可能你在业务逻辑里,除了依赖数据库以外,还依赖了别的服务接口,或者是 elasticsearch、redis 等多种数据存储,也可能是依赖了数据库中的多张表里的数据,你不可能每张表都做一个唯一索引来确保幂等性。

1648175669411.png

# 解法2,分布式锁来实现幂等

依赖外部的某个系统来加一把锁,锁加了以后后续还可以释放这把锁,现在比较常见的分布式锁实现主要是依赖 redis 和 zookeeper 这两个来实现的.

我们可以在接口的入口代码处,基于 redis 加一把分布式的锁,这个时候只有一个线程可以成功加锁。 加锁之后,就这一个线程就可以去查询这条数据是否存在,如果不存在,就可以插入一条数据进去,然后再释放锁,在这个过程中,另外一个线程因为获取不到 redis 分布式锁,所以只能干等着。

1648175136644.png

全量分析

评 论:

上次更新时间: 3/26/2022, 1:54:58 PM