qnmd bd:待会劳资就去买个vpn。

在平常的工作中经常听到也用到幂等,却没有及时学习总结这个知识点,现在到时候了。

幂等性最初是一个数学上的概念:在某二元运算下,幂等元素是指被自己重复运算(或对于函数是为复合)的结果等于它自己的元素。用公式来表示就是:

\(f(x) = f(f(x))\)

数学就是这么抽象,用自己的语言去描述一个概念,置于这个概念的含义有多么丰富就看自己的领会。反正我看到这个是一脸蒙蔽的。高中做这种题目的时候就很蛋疼。

如果放在web应用,可以这么理解幂等:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击(提交请求)而产生了副作用。

如果你去网上查关于幂等的博客大多数都是这么讲的。但是我还是觉得这个有点蛋疼。

什么叫"结果一致":比如对于同一个订单来说,第一次支付请求失败了,然后重试第二次支付请求成功了,然后接着又发出了一次支付请求结果成功了。那么这个结果是不是一致的呢?其实,这里的"结果一致"是我理解错了,幂等中的结果不是对于用户来说是否支付成功的状态,而是指的业务上,一个订单至多只能有一个成功的支付请求。

所以上面说的可以分析如下几个要点:

同一操作:同一种类型的操作(增,删,改,查),参数要一样。比如,对同一个订单号进行支付就是同一操作,而记录不同时刻的水位就不是同一操作,自己理解一下。

隐含条件:就是这里被坑了一下,编程中由操作失败的时候呀,比如支付;但是\(f(x) = f(f(x))\)只要\(x\)在定义域,\(f(x)\)总是成功的。所以这里操作,其实指的是操作成功,不成功的操作总是幂等的呀,别跟我说成功了一半,去屎吧。所以这里的结果指的是操作成功的结果,不包含失败的结果。这个地方可能有争议,失败也分为很多情况,有的是操作发出去的过程中因网络不通而失败,也可能是处理请求的逻辑失败,所以失败也可能有副作用(修改了状态,或者值)。

结果一致:这个结果是业务中的一种规则,比如通常情况下,一个订单最多只有一个成功的支付请求。假如有一个操作记录表的话,这个成功的操作记录最多也只有一条。

网上的做法大概有两种:

第一种:使用ticket

  1. 从某个地方(服务,池或者工具类,或者其他什么地方)获取一个ticket
  2. 在调用服务的时候传入这个ticket
  3. 服务在内部处理的时候会先查询这个ticket操作是否存在,如果不存在则说明这个没有被操作过,直接执行;如果发现了这个ticket存在,则直接返回
  4. 服务把结果返回给客户端

第二种:查询支付状态,然后再决定是否去更新

这两种方法都会导致并发问题:

这两个方法都有一个问题,以方法一为例:
根据ticket查询此次操作是否存在,如果存在则表示该操作已经执行过,直接返回结果;如果不存在,支付扣款,保存结果
如果第二次调用的时候第一次正在处理,但是没有处理完,第二次怎么去返回结果?或者说第二次在查询此次操作的时候是不是查不到第一次的操作?
方法二也是一样的,先查后支付,那两次同时调用都查到没有支付然后去扣款,还是有并发的问题

解决这个并发问题有人提出了用分布式锁。所以分布式锁怎么实现呢?

引出话题:

  1. 订单和支付系统的设计
  2. 分布式锁

web应用中幂等性的学习的更多相关文章

  1. Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

    本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...

  2. 高访问量WEB开发中的架构模式,学习从点滴开始

     当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架构 ...

  3. tornado学习笔记11 Web应用中模板(Template)使用应用实践

    上一篇中(Web应用中模板的工作流程分析),已经分析了模板的渲染流程,以及相关参数获取及设置原理.这篇主要讲述模板在实际应用案例. 11.1 需求 根据用户输入的两次密码,判断两次密码是否一致,并将判 ...

  4. HTTP学习二:Web应用中的HTTP

    1 HTTP连接 1.1 TCP连接对性能的影响 TCP三次握手如下图: 如上图,建立一次TCP连接要经过三个步骤.HTTP是建立在TCP之上的,因此TCP连接的性能直接影响HTTP的性能. TCP影 ...

  5. spring web mvc中遇到的错误以及学习小记(持续记录)

    错误:cvc-complex-type.2.4.a: 发现了以元素 'init-param' 开头的无效内容.应以 '{"http://java.sun.com/xml/ns/javaee& ...

  6. java web开发中遇到的问题及解决方案(个人学习日志,持续更新)

    转:http://blog.csdn.net/ducexu/article/details/7529613 2012.05.02   星期三 1.问题:导入的新工程,名字上出现感叹号. 原因:工程的j ...

  7. SpringBoot学习(七)-->SpringBoot在web开发中的配置

    SpringBoot在web开发中的配置 Web开发的自动配置类:在Maven Dependencies-->spring-boot-1.5.2.RELEASE.jar-->org.spr ...

  8. Java嵌入式数据库H2学习总结(三)——在Web应用中嵌入H2数据库

    H2作为一个嵌入型的数据库,它最大的好处就是可以嵌入到我们的Web应用中,和我们的Web应用绑定在一起,成为我们Web应用的一部分.下面来演示一下如何将H2数据库嵌入到我们的Web应用中. 一.搭建测 ...

  9. 重新学习Spring一--Spring在web项目中的启动过程

    1 Spring 在web项目中的启动过程 Spring简介 Spring 最简单的功能就是创建对象和管理这些对象间的依赖关系,实现高内聚.低耦合.(高内聚:相关性很强的代码组成,既单一责任原则:低耦 ...

随机推荐

  1. idea maven 报-source 1.5 中不支持 diamond 运算符

    需要修改 project setting 中的

  2. Woocommerce 分类下的产品如何使用ID号来作为默认排序字段

    在给一个客户开发网店系统时使用了WordPress系统的Woocommerce插件 WordPress版本:3.8 Woocommerce版本:2.0.20 如果没有指定排序规则(指定的字段),则Wo ...

  3. 转:Mac OS X下Sublime Text (V2.0.1)破解

    Mac OS X下Sublime Text (V2.0.1)破解 Mac OS X下Sublime Text (V2.0.1)破解 (2013-03-07 14:02:54) 转载▼     正版的买 ...

  4. CLS(公共语言规范)的CLSCompliant(跨语言调用)

    .net的一个很重要的特性就是跨语言的编程,用C#写的dll可以在VB.net里调用,例如:用C#写的一个类,编译到dll中,然后在VB.net中调用: using System;namespace  ...

  5. [AngularJS] $scope.$watch

    /** * Created by Answer1215 on 11/13/2014. */ function MainCtrl($scope){ function isLongEnough (pwd) ...

  6. 第一章:走近java-深入理解java虚拟机-读书总结

    java技术体系: 1.java程序设计语言 2.硬件平台上的java虚拟机 3.class文件格式 4.java的API类库 5.第三方的类库 JDK: java语言,虚拟机,java API类库  ...

  7. eclipse因为js validator无法通过导致build workspace失败

    eclipse编译工程时时会validator js的errors和warnings,对于一些小型的项目,这当然没任何问题. 但是对于那些拥有大量js文件的web工程,js warnings通常会达到 ...

  8. 错误代码: 1066 Not unique table/alias: 'c'

    1.错误描写叙述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:SELECT (SELECT CONCAT( s.name, '/', ...

  9. ubuntu 设置计划任务

    非常简便: crontab -e 以下是我的执行过程,输入命令后,会让我选择一个编辑器,我选的是2,因为后边写着easiest,最简单的. liuyx@myubuntu:/$ crontab -e n ...

  10. Android系统示例分析之AccelerometerPlay

    程序界面: 创建 SimulationView , 实现接口 SensorEventListener , 实现接口中两个抽象方法 public void onSensorChanged(SensorE ...