幂等性
2020-03-25 16:08:26来源:博客园 阅读 ()
幂等性
幂等性的概念
对于同一操作发起的请求(一次或者多次请求),任意多次执行对资源本身产生的影响均与一次执行产生的影响相同,不会因为多次相同操作而产生副作用。
比如一个用户注册,点击“注册”,由于某些原因(比如服务器负载大),长时间转圈圈,你多次点击“注册”,这多次请求都是完全相同的,应该只插入一条用户记录,而不是点多次“注册”每次都插入一条用户记录。
比如下单购买,点击“提交”,卡住了,什么破手机|网络,疯狂点“提交”,这多次请求完全相同,应该只产生一个订单,而不是每次点击都产生一个订单。
http请求方式(restful)
在其他条件不变的情况下(资源没有被其它操作修改):
- get 查询,相同的查询操作,比如select username where id=1 from tb_user;执行多次,查询到的结果都是相同的,get是幂等的
- post 插入,相同的插入操作,比如insert into tb_order (...) values (...); 执行多次,虽然可能会因为主键已存在、某个字段的值要唯一等原因插入失败,但每次都会尝试插入一条新纪录,如果满足约束,每次都会插入一条记录,结果可能不同(产生了新纪录),post不是幂等的
- put 更新,相同的更新操作,比如update tb_user username='chy',age=20 where id=1; 不管执行多少次,id=1的这条记录,name都是chy,age都是20,结果都是相同的,put是幂等的
- delete 删除,相同的删除操作,比如delete from tb_user where id=1 ,不管执行多少次,结果都是删除了id=1的记录,结果相同,delete是幂等的
消息消费者与幂等性
消息可能会被重复投递、消费,比如第一次投递的消息还在queue中,为确保消息投递的可靠性,延时又投递了一次消息,消费者应确保同一消息只进行一次消费。
幂等常见的实现方式
核心思想:
使用唯一的业务单号来标识一个业务,如果业务单号相同,就认为是同一笔业务,只执行一次。(去掉重复的业务)
存储执行过的业务的业务单号,先根据业务单号查询这笔业务是否已经执行过了,如果没执行过,才执行。
如果系统是单线程的,查询单号、执行这笔业务2个过程都不用加锁;如果过多个线程并发访问执行过的业务单号(有读有写),就需要给执行过的业务单号加锁(幂等是查询时加锁),执行过程往往也需要给共享数据加锁。
业务单号可以用流水号,也可以唯一id+指纹码,总之要能唯一标识一笔业务。
比如order的id,只用id是可以唯一标识一个订单,但不能标识是这个order的增改删查哪个业务,也不能标识是这个order的第几次修改操作。需要再加一个指纹码,比如时间戳、业务规则什么的。
1、数据库主键去重
单独用一张tb_order_ handled来存储执行过的订单的业务单号,使用列no存储业务单号(主键、unique约束),外键order_id关联order表的id,
执行业务时先select count(*) from tb_order_handled where no=xxx; 根据业务单号查询这笔业务是否已执行,数量为1表示有这条记录,这笔业务已处理过,不再处理;为0表示没处理过,就处理这笔业务。
这种方式的缺点是增加了数据库IO次数,数据库性能很容易成为系统性能的瓶颈,往往需要分库分表把业务单号所在的表拆分出来,来提升数据库性能。
如果这个服务只有数据库更新操作的话,也可以使用数据库的乐观锁(版本号机制)。
2、分布式锁(推荐)
把处理过的业务单号作为键值对的key,存储在redis上,处理业务时先查询redis上有没有这个key,有就说明处理过了,不再处理,没有就说明这笔业务没有处理过,开始处理。
简单、且性能高,推荐。
3、缓冲区
把一段时间内要处理的业务都放到缓冲区中,先去掉重复的业务,再执行。
缺点:处理有时延、不能马上返回处理结果。不太常用。
原文链接:https://www.cnblogs.com/chy18883701161/p/12561765.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- JAVA自定义注解 2020-06-01
- DDD之2领域概念 2020-05-30
- 高级java必须清楚的概念:原子性、可见性、有序性 2020-05-13
- 学习java多线程,这必须搞懂的这几个概念,很重要。 2020-05-07
- Java程序员如何了解继承和接口这两个概念 2020-05-07
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash