资讯专栏INFORMATION COLUMN

幂等性的作用及实现

Java3y / 1606人阅读

摘要:保证幂等性的方法建立唯一索引,防止新增脏数据这个可以限制重复插入数据,当重复时,数据库会抛异常,保证不会出现脏数据。它用来解决分布式系统的幂等性,常用的实现方案是和等工具。

幂等性

幂等这个词原自数学,某一元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同。在编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。第一次请求的时候对资源产生了副作用,但是以后的多次请求都不会再对资源产生副作用。这里的副作用是不会对结果产生破坏或者产生不可预料的结果。

比如,某服务记录关键数据 X,当前值为 100。A 请求需要将 X 增加 200;同时,B 请求需要将 X 减去 100。在理想的情况下,A 先读取到 X=100,然后 X 增加 200,最后 X=300。B 请求接着从读取 X=300,减去 100,最后 X=200。 然而在真实情况下,如果不做任何处理,则可能会出现:A 和 B 同时读取到 X=100;假如 A 比 B 先执行完,那么最后 X=0,如果 B 比 A 先执行完,那么最后 X=300。不管是那种情况发生了,都产生了副作用或者说是产生了不可预料的结果,并且是不可以接受的异常。这种情况就是我们提供的方法或者接口不满足幂等性,导致的不可预料的结果。

保证幂等性的方法

1.建立唯一索引,防止新增脏数据
这个可以限制重复插入数据,当重复时,数据库会抛异常,保证不会出现脏数据。但体验不好,并且实用场景有限制。

2.利用 token 机制,防止页面重复提交
核心思想是为每一次操作生成一个唯一性的凭证,也就是token。一个token在操作的每一个阶段只有一次执行权,一旦执行成功则保存执行结果。对重复的请求,返回同一个结果。

3.状态机幂等
在有状态的数据中可以使用,如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等。如果状态是顺序的,不可逆,那么就不会出现 ABA 问题,否则会出现 ABA问题。

4.select + insert
这种情况在没有并发的系统中可以解决幂等问题,在单JVM有并发的时候可以加锁来保证幂等性,在分布式环境它是没发保证幂等的,这时候需要用到分布式锁来保证。

5.分布式锁
在进入方法时,先去获取锁,假如获取到锁,就继续后面的流程。假如没有获取到锁,就等待锁的释放直到获取到锁。当执行完方法时,释放锁。当然,锁要设个超时时间,防止意外没有释放到锁。它用来解决分布式系统的幂等性,常用的实现方案是 redis 和 zookeeper 等工具。

6.对外提供幂等的接口
通过 source来源+seq序列号来判断请求是否重复, 在并发时只能处理一个请求。其它相同并发请求要么返回请求重复,要么等待前面请求执行完成在执行。

幂等性的不足

1.增加了额外控制幂等的业务逻辑,复杂化了业务功能。
2.把并行执行的功能改为串行执行,降低了执行效率。

最后,幂等性虽然复杂化了业务功能和降低了执行效率,但为了保证系统的正确性,是必要的。就上面更新 X 的例子,在单台服务器上,给那段代码加上锁,并给 X 设为 volatile,就保证来数据的正确性了。在分布式环境下并且 X 是从数据库或者文件里查询出来的,用上面加锁的方式实现就不能保证数据的正确性了,这时候就需要用到分布式锁了。所以,保证方法或接口的幂等性是非常有必要的,因为数据是不能出现任何问题的。

PS:
清山绿水始于尘,博学多识贵于勤。
微信公众号:「清尘闲聊」。
欢迎一起谈天说地,聊代码。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37213.html

相关文章

  • 通过实际业务场景理解后端接口的等性

    摘要:有些接口可以天然的实现幂等性,比如查询接口,对于查询来说,你查询一次和两次,对于系统来说,没有任何影响但对于有写库操作的增删改接口,多次调用就会对系统有多次影响。 写在前面:之前在设计接口时因经验尚浅,并未过多考虑幂等性,但这两天出现的一个线上问题让我认识到了某些情况下接口幂等性的重要性; 非幂等场景:服务A将单据A信息通过RPC远程过程调用传给下游服务B接口(非幂等接口)用于生成关联...

    赵春朋 评论0 收藏0
  • 【Java】几道常见的秋招面试题

    摘要:总结的时间复杂度是,是空间是使用辅助栈来存储最小值。项目就是为了解决配置繁琐的问题,最大化的实现约定大于配置。 前言 只有光头才能变强 Redis目前还在看,今天来分享一下我在秋招看过(遇到)的一些面试题(相对比较常见的) 0、final关键字 简要说一下final关键字,final可以用来修饰什么? 这题我是在真实的面试中遇到的,当时答得不太好,现在来整理一下吧。 final可以修饰...

    Rocko 评论0 收藏0
  • RabbitMQ消息等性设计

    摘要:消息幂等性设计可能导致消息出现非幂等性的原因可靠性投递机制比如消息已经发送出去,已经收到了,然后在返回的时候网络出现闪断,导致未收到应答,导致发送两次。消费端故障异常。 RabbitMQ消息幂等性设计 可能导致消息出现非幂等性的原因: 1 可靠性投递机制:比如消息已经发送出去,mq已经收到了,然后mq在返回confirm的时候网络出现闪断,导致broker未收到应答,导致发送两次。...

    BicycleWarrior 评论0 收藏0
  • kafka消息队列

    摘要:为什么使用消息队列消息队列的优缺优点解耦异步消峰缺点系统的可用性降低,系统引入的外部依赖越多,越容易挂掉系统复杂性提高数据一致性问题常用消息队列的优缺点技术非常成熟,但是偶尔会出现较低概率的丢失消息,而且现在社区以及国内应用都越来越少社区相 为什么使用消息队列消息队列的优缺 1优点 (1) 解耦 (2) 异步 (3) 消峰 2 缺点 (1)系统的可用性降低,系统引入的外部依赖越多...

    godlong_X 评论0 收藏0
  • 五万字15张导图Java自学路线,小白零基础入门,程序员进阶,收藏这篇就够了

    摘要:本文收录于技术专家修炼文中配套资料合集路线导图高清源文件点击跳转到文末点击底部卡片回复资料领取哈喽,大家好,我是一条最近粉丝问我有没有自学路线,有了方向才能按图索骥,事半功倍。 ...

    suosuopuo 评论0 收藏0

发表评论

0条评论

Java3y

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<