20200117 实现接口幂等的几种方式

实现接口幂等性,防止并发操作,如何设计接口幂等方案?

当前是否有高并发的场景,如果是才需要处理接口幂等操作,如果不是就不需要处理。

插入更改操作,都要考虑高并发条件下的幂等性。

接口的幂等性实际上就是接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。

 

在高并发条件下,如果每秒200个线程注册,有可能num=-2, 验证成功,导致数据落库,所以应该是<= -1

 

1、redis:setNX实现分布式锁,防止多个相同操作同时执行。

2、mysql:select......for update (悲观锁) ,配合Spring事务一起使用,可以防止更新丢失。

3、前后端交互:前端调用接口时,先从后端获取一个令牌;请求接口时,后端直接删除当前令牌,如果删除成功,继续执行;如果删除失败,返回正在处理中。

4、mysql:使用数据库的唯一索引机制,比如对订单号创建唯一索引,防止订单号的重复。

5、mysql:通过数据库版本号实现幂等操作,通过mysql实现乐观锁(更新操作)。

6、redis分布式锁:在业务系统插入数据或者更新数据,获取分布式锁,然后做操作,之后释放锁,这样其实是把多线程并发的锁的思路(redis的实现有多种方式,原子操作,递增,递减)

7、mysql联合唯一索引:一个特定的业务场景,三个字段肯定确定唯一性,那么,可以在数据库表添加唯一索引来进行标示。

8、有限状态机幂等,通过某种指定状态才能更新成下个状态。

9、类似double check机制的确认机制

 

悲观锁和乐观锁大部分场景下差异不大,一些独特场景下有一些差别,一般我们可以从如下几个方面来判断:

1)响应速度:如果需要非常高的响应速度,建议采用乐观锁方案,成功就执行,不成功就失败,不需要等待其他并发去释放锁

2)冲突频率:如果冲突频率非常高,建议采用悲观锁,保证成功率,如果冲突频率大,乐观锁会需要多次重试才能成功,代价比较大

3)重试代价:如果重试代价大,建议采用悲观锁。

3、redis分布式锁,支付完删除值,所以可以防止多次提交。

 

SETNX key value

将ke的值设为value,当且仅当key不存在。若给定的key已经存在,则SETNX 不做任何动作。

返回值:设置成功,返回1。设置失败,返回0。

SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。

 

行锁,排它锁:

for update是在数据库中上锁用的,可以为数据库中的行上一个排它锁。当一个事务的操作未完成时候,其他事务可以读取但是不能写入或更新。

如果查询不到,锁失效? 如果查询不到,同时进行插入操作,还是会插入多条重复的记录。

但是请注意如果查询范围比较大有可能会锁住整张表,确定主键索引才能使用

 

注意:当选中某一个行的时候,如果是通过主键id选中的,那么这个时候是行级锁。 

其他行还是可以直接insert 或者update的。如果是通过其他的方式选中行,或者选中的条件不明确包含主键,这个时候会锁表。其他的事务对该表的任意一行记录都无法进行插入或者更新操作,只能读取。

 

锁定一行还是锁定多行,还是锁表? 这个尽量别使用,如果锁表将会导致整个项目性能低下。

 

删除操作:设置过期时间为2分钟,两分钟内还没请求,令牌自动失效。

幂等操作校验,可以通过注解来实现么? 完全可以封装一个注解。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值