概述
- 什么是幂等性
- 幂等性设计的核心思想
- select、update、 delete、 insert和混合操作的接口幂等性
接设计与重试机制引发的问题
接口幂等性
- 提交订单按钮如何防止重复提交? .
- 表单录入页如何防止重复提交?
- 微服务接口,客户端重试时,会对业务数据产生影响吗?
什么是幂等性
- 幂等性: f(f(x)) = f(x)
- 幂等元素运行多次,还等于它原来的运算结果
- 在系统中,-个接口运行多次,与运行一-次的效果是一致的
什么情况下需要幂等性
重复提交、接口重试、前端操作抖动等
业务场景:用户多次点击提交订单,后台应只生成一个订单。
支付时,由于网络问题重发,应该只扣一次钱。
并不是所有的接口都要求幂等性,要根据业务而定
保证幂等性的策略有哪些?
幂等性的核心思想:通过唯一的业务单号保证幂等
非并发情况下,查询业务单号有没有操作过,没有则执行操作
并发的情况下,整个操作过程加锁
Select操作:不会对业务数据有影响,天然幂等
Delete操作:第一次已经删除,第二次也不会有影响
Update操作:更新操作传入数据版本号,通过乐观锁实现幂等性
Insert操作:此时没有唯一-业务单号 ,使用Token保证幂等
混合操作:找到操作的唯一业务单号, 有则可使用分布式锁,没有可以通过Token保证幂等
Delete 操作的幂等性
-
根据唯一业务号去删除
第一次删除时,已将数据删除
第二次再次执行时,由于找不到记录,所以返回的结果是0,对业务数据没有影响。可在删除前进行数据的查询。 -
删除操作没有唯一业务号, 则要看具体的业务需求
例如:删除所有审核未通过的商品。
第一次执行,将所有未通过审核的商品删除
在第二次执行前,又有新的商品未审核通过。
执行第二_次删除操作,新的未审核通过的商品要不要删除?
根据业务需求而定
Update操作的幂等性
根据唯一业务号去更新数据的情况
用户查询出要修改的数据,系统将数据返回页面,将数据版本号放入隐藏域
用户修改数据,点击提交,将版本号一同提交给后台
后台使用版本号作为更新条件
update set version=version+ 1 ,XXX= ${xxx} where id=xxx and version = ${version}
使用乐观锁与update行锁,保证幂等
Insert操作的幂等性
有唯一业务号的Insert操作,例如:秒杀,商品ID+用户ID
可通过分布式锁,保证接口幂等
业务执行完成后,不进行锁释放,让其过期自动释放
没有唯一业务号的Insert操作,比如:用户注册,点击多次
使用Token机制,保证幂等性
进入到注册页时,后台统一生成Token,返回前台隐藏域中