MySQL数据库工程师入门实战课程视频教程
5160 人在学
简单来说是本身可视为 电子化的文件柜——存储电子 文件的处所,用户可以对文件中的数据进行新增、截取、更新、删除等操作。
幂等概念来自数学,表示对数据源做N次变换和1次变换的结果是相同的。在工程中幂等性用来表示用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
幂等概念来自数学,表示对数据源做N次变换和1次变换的结果是相同的。在工程中幂等性用来表示用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
业务开发时,可能会遇到由于网络震荡导致请求无法收到导致触发了重试机制,或者前端抖动导致表单重复提交这样的情况。比如在交易系统中,用户提交购物请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被掉丢了,导致客户端无法得知处理结果。如果是在网页上,一些不恰当的设计可能会使用户认为上一次操作失败了,然后刷新页面,这就导致了扣款被调用两次,账户也被多扣了一次钱。此时就需要引入幂等性接口了。
我们以MySQL为例,只有第三种场景需要开发人员使用其他策略保证幂等性:
这里说下重复提交跟幂等性的区别:
引入幂等性后会使得服务端逻辑更加复杂,满足幂等性的服务需要在逻辑中至少包含两点:
首先去查询上一次的执行状态,如果没有则认为是第一次请求。
在服务改变状态的业务逻辑前,保证防重复提交的逻辑。
幂等性可以简化客户端逻辑处理,但却增加了服务提供者的逻辑和成本,所以是否要用,需根据具体场景具体分析,因此除了业务上的特殊要求外,尽量不提供幂等的接口。
增加了额外控制幂等的业务逻辑,复杂化了业务功能。
把并行执行的功能改为串行执行,降低了执行效率。
在用户点击完提交按钮后,我们可以把按钮设置为不可用或者隐藏状态。
前端限制比较简单,但有个致命错误,如果碰到懂行的用户通过模拟网页请求来重复提交请求,绕过了前端限制。
防止订单多次插入的最简单直接方法就是创建唯一索引,然后插入的时候可能语句有细微的不同。但目的都是保证相同记录在数据库中只存在一条。
去重表的机制是根据mysql唯一索引的特性来的,大致流程:
方式一:简单的利用java自带的syn 或 lock 锁实现幂等性。核心点在于将重要的执行部分将并行切换为串行。缺点是这个锁在分布式场景是不能用的,因为都跨JVM了!此时需要引入分布式锁了。
依靠MySQL自带的for update操作数据库,来实现串行化。这里的重点在于for update,简单说明下:
该模式的缺点是,如果业务处理比较耗时,并发情况下,后面线程会长期处于等待状态,占用了很多线程,让这些线程处于无效等待状态,而web服务中的线程数量一般有限的,如果大量线程由于获取for update锁处于等待状态,不利于系统并发操作。
对每行数据添加个version字段,这里其实跟秒杀设计中的思路类似,利用MySQL自带的当前读更新操作。在更新数据时候先查询获得对应版本号,然后尝试update操作,根据返回值是否为0来确保是否是重复提交。
使用Redis中的setnx操作,将幂等性的保证屏障设置在分布式锁中。如果setnx成功了说明这是第一次进行数据插入,继续执行SQL语句即可。如果setnx失败了,那说明已经执行过了。
这种方式分成两个阶段:申请token阶段和支付阶段。
实际上这里的token可以认为是一个信物,支付系统根据token确认插入的唯一性。token模式不足之处在于,需要系统间交互两次,流程较上述方法复杂。
严格来说,数据库是长期储存在计算机内、有组织的、可共享的数据集合。数据库中的数据指的是以一定的数据模型组织、描述和储存在一起、具有尽可能小的冗余度、较高的数据独立性和易扩展性的特点并可在一定范围内为多个用户共享。