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. 【问题】VH

      [问题]: CSS中使用了VH,在iOS中展示正常,但是在安卓的个别浏览器中,当输入框弹出时,使用VH的DIV的高度会发生变化. [原因]: 在安卓端浏览器虚拟键盘弹出时,导致视口高度改变,以至于 ...

  2. MongoDB 聚合管道(aggregate)

    1.aggregate() 方法 我们先插入一些测试数据 { "_id" : ObjectId("5abc960c684781cda6d38027"), &qu ...

  3. T-SQL 之 语法元素

    一.标识符 在T-SQL语言中,对SQLServer数据库及其数据对象(比如表.索引.视图.存储过程.触发器等)需要以名称来进行命名并加以区分,这些名称就称为标识符. 通常情况下,SQLServer数 ...

  4. [Ext JS 4] 实战之 带week(星期)的日期选择控件

    前言 Ext JS 3 和 Ext JS 4中都有提供日期选择的组件(当然早期版本也有). 但是有一些日期选择的需求是要看到星期,就是日期中的哪一天是这一年的第几周. 遗憾的是Ext js 并没有提供 ...

  5. POI按行读取word,并去掉属性标签内容:超链接

    public String readDoc(File file) { StringBuffer buffer = new StringBuffer(); InputStream input = nul ...

  6. Burning widget

    This is a widget that we can see in Nero, K3B, or other CD/DVD burning software. #!/usr/bin/python # ...

  7. wait & waitpid 以及子进程传给父进程的信号分析

    wait() 和 waitpid() wait() 系统调用挂起调用进程的执行直到有一个孩子终止.调用 wait(&status) 等价于: waitpid(-1, &status, ...

  8. linux 挂载 ISO 文件

    sudo sudo mount -o loop SUSE-Linux-10.1-GM-DVD-x86_64.iso /media/cdrom/ sudo umount /media/cdrom

  9. 数据库选型之MySQL(固态硬盘)

    刘勇    Email: lyssym@sina.com 本博客记录作者在工作与研究中所经历的点滴,一方面给自己的工作与生活留下印记,另一方面若是能对大家有所帮助,则幸甚至哉矣! 简介 鉴于高频中心库 ...

  10. Android 应用开发实例之文件管理器

    2013-07-02 10.2 文件管理器 能够浏览和管理手机/存储卡上的文件和文件夹,包括重命名.删除.新建.复制.粘帖等文件操作. 由于需要浏览大量的文件/文件夹,所以需要使用一个ListView ...