幂等性的拙见

幂等性

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

好比,某服务记录关键数据 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.对外提供幂等的接口
经过 来源+序列号 来判断请求是否重复, 在并发时只能处理一个请求。其它相同并发请求要么返回请求重复,要么等待前面请求执行完成在执行。工具

幂等性的不足

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

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

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

相关文章
相关标签/搜索