幂等设计

为什么要做幂等?

幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的。

例如

1、 前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果。

2、 我们发起一笔付款请求,应该只扣用户账户一次钱,当遇到网络重发或系统bug重发,也应该只扣一次钱;

3、 发送消息,也应该只发一次,同样的短信发给用户,用户会哭的;

4、 创建业务订单,一次业务请求只能创建一个,创建多个就会出大问题。

如何保证幂等?

  1. 查询
    查询天然幂等。

  2. 添加
    通过业务唯一键保证:
    当插入时抛出DuplicateKeyException异常时表示已经插入成功
    或考虑INSERT IGNORE INTO和REPLACE INTO

  3. 删除
    删除也是天然的幂等,删除一次和多次删除都是把数据删除。(注意可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条,返回结果多个)

  4. MVCC方案
    多版本并发控制,update with condition,更新带条件,这也是在系统设计的时候,合理的选择乐观锁,通过version或者其他条件,来做乐观锁,这样保证更新及时在并发的情况下,也不会有太大的问题。例如update table_xxx set name=#name#,version=version+1 where version=#version#,或者是 update table_xxx set quality=quality-#subQuality# where quality-#subQuality# >= 0

  5. 悲观锁
    获取数据的时候加锁:select * from table_xxx where id='xxx' for update;

注意:

  • id字段一定是主键或者唯一索引,不然是锁表,会死人的
  • 悲观锁使用时一般伴随事务一起使用,数据锁定时间可能会很长,根据实际情况选用

单独的去重表
分布式锁
状态机幂等
API层token机制
​ 由于重复点击或者网络重发,或者nginx重发等情况会导致数据被重复提交。

参考
https://www.jianshu.com/p/37537fdb170f
https://www.jianshu.com/p/00cf7d7abbf7
https://www.jianshu.com/p/972ce0c98ce2
http://chuanwang66.iteye.com/blog/1328563
http://blog.720ui.com/2017/server_statemachine/
https://www.jianshu.com/p/475589f5cd7b
http://www.daydaytc.com/mysql/42.html
https://www.jianshu.com/p/e4fb0325b252

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容