Survive by day and develop by night.
talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge Survive.
happy for hardess to solve denpendies.
目录
概述
幂等性如何保证
需求:
设计思路
实现思路分析
1.URL管理
幂等概念来自数学,表示对数据源做N次变换和1次变换的结果是相同的。在工程中幂等性用来表示用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
幂等包括第一次请求的时候对资源产生了副作用,但是以后的多次请求都不会再对资源产生副作用。
幂等关注的是以后的多次请求是否对资源产生的副作用,而不关注结果。
网络超时等问题,不是幂等的讨论范围。
幂等性是系统服务对外一种承诺,而不是实现,承诺只要调用接口成功,外部多次调用对系统的影响是一致的。声明为幂等的服务会认为外部调用失败是常态,并且失败之后必然会有重试。
我们以MySQL为例,只有第三种场景需要开发人员使用其他策略保证幂等性:
1.3 幂等性思考
引入幂等性后会使得服务端逻辑更加复杂,满足幂等性的服务需要在逻辑中至少包含两点:
首先去查询上一次的执行状态,如果没有则认为是第一次请求。
在服务改变状态的业务逻辑前,保证防重复提交的逻辑。
幂等性可以简化客户端逻辑处理,但却增加了服务提供者的逻辑和成本,所以是否要用,需根据具体场景具体分析,因此除了业务上的特殊要求外,尽量不提供幂等的接口。
增加了额外控制幂等的业务逻辑,复杂化了业务功能。
把并行执行的功能改为串行执行,降低了执行效率。
2 幂等性解决
2.1 前端设置
在用户点击完提交按钮后,我们可以把按钮设置为不可用或者隐藏状态。
2.2 唯一索引
防止订单多次插入的最简单直接方法就是创建唯一索引,然后插入的时候可能语句有细微的不同。但目的都是保证相同记录在数据库中只存在一条。
方法一:给数据库添加唯一索引,然后如果执行时捕捉到了DuplicateKeyException会明白是重复插入导致的,继续往下执行业务即可。
方法二:利用MySQL自带的关键字ON DUPLICATE KEY UPDATE 实现不存在则插入,存在则更新的操作,该关键字不会删除原有的记录。
方法三:replace into 主要作用类似 INSERT 插入操作,replace into底层是先删除后插入数据,会破坏索引、重新维护索引。需注意必须要有主键或唯一索引才能有效,否则replace into就只新增了。
2.3 去重表
去重表的机制是根据mysql唯一索引的特性来的,大致流程:
判断是否插入成功,如果插入成功,则继续做后续业务请求。如果插入失败,则代表已经执行过当前请求。
2.4 悲观锁
方式一:简单的利用Java自带的syn 或 lock 锁实现幂等性。核心点在于将重要的执行部分将并行切换为串行。缺点是这个锁在分布式场景是不能用的,因为都跨JVM了!此时需要引入分布式锁了。
方式二:
依靠MySQL自带的for update操作数据库,来实现串行化。这里的重点在于for update,简单说明下:
当线程A执行for update,数据会对当前记录加锁,其他线程执行到此行代码的时候,会等待线程A释放锁之后,才可以获取锁,继续后续操作。
事物提交时,for update获取的锁会自动释放。
该模式的缺点是,如果业务处理比较耗时,并发情况下,后面线程会长期处于等待状态,占用了很多线程,让这些线程处于无效等待状态,而web服务中的线程数量一般有限的,如果大量线程由于获取for update锁处于等待状态,不利于系统并发操作。
2.5 乐观锁
对每行数据添加个version字段,这里其实跟秒杀设计中的思路类似,利用MySQL自带的当前读更新操作。
2.6 分布式锁
使用Redis中的setnx操作,将幂等性的保证屏障设置在分布式锁中。如果setnx成功了说明这是第一次进行数据插入,继续执行SQL语句即可。如果setnx失败了,那说明已经执行过了。
2.7 token 方案
这种方式分成两个阶段:申请token阶段和支付阶段。
第一阶段:在进入到提交订单页面之前,需要订单系统根据用户信息向支付系统发起一次申请token的请求,支付系统将token保存到Redis缓存中,为第二阶段支付使用。
第二阶段:订单系统拿着申请到的token发起支付请求,支付系统会检查Redis中是否存在该token,如果存在,表示第一次发起支付请求,删除缓存中token后开始支付逻辑处理;如果缓存中不存在,表示非法请求。
参考资料和推荐阅读
- 暂无
- https://mp.weixin.qq.com/s?__biz=MzIyMTQ4OTM3NQ==&mid=2247506392&idx=2&sn=4f47ac8f08d14fbab5b2e51fcda0f99b&chksm=e8396868df4ee17e646da5194e687077715fbfb0a7b1107988ce7cdfec51d696057c91696d88&scene=27
欢迎阅读,各位老铁,如果对你有帮助,点个赞加个关注呗!~