性能测试
持续更新…
标记
系列文章目录-性能测试
性能测试-基础+中级(二)【前端性能测试】
文章目录
- 系列文章目录-性能测试
- 性能测试-基础+中级(二)【前端性能测试】
- 1. 性能测试起步
- 1.1 性能测试的应用场景
- 1.2 不同的角度看性能
- 1.3 影响性能的因素
- 2. 性能测试概述
- 2.1 性能测试定义和分类
- 2.2 常用性能测试术语、性能测试指标
- 3. 性能测试流程
- 3.1 性能测试准备
- 3.2 性能测试流程
- 3.2.1 性能测试开展阶段
- 3.2.2 功能测试流程与性能测试流程对比
- 3.2.3 性能测试流程
- 3.3 性能测试的专业分析
- 3.4 性能测试用例设计
- 4. 所需技能和工具选择
- 4.1 所需技能
- 4.2 测试工具选择
- 5. 性能理论模型
- 5.1 理发店模型
- 5.2 性能测试拐点模型
- 6. MySQL
- 6.1 MySQL进行事务管理
- 6.1.1 自动事务(MySQL默认)
- 6.1.2 手动事务管理
- 6.1.3 回滚点
- 6.2 事务特性和隔离级别
- 6.2.1 事务特性
- 6.2.2 事务隔离级别
- 6.3 数据的备份和还原
1. 性能测试起步
1.1 性能测试的应用场景
- 选型
系统采用新技术或新架构,但是这种新技术/新架构是否能够满足我们的业务需求尚且未知,如果等待系统开发完毕后再去验证是否满足业务需求,风险较高。所以在选型的时候,就去对采用的新架构或新技术做性能测试,验证是否满足比如大并发这种业务需求,从而更早的规避风险。 - 验收
系统功能测试已经通过,这时候就需要在业务需求的场景下对系统做性能测试,看是否能满足性能的需求。 - 备份
比如系统部署在阿里云服务器上,但为避免挂掉无顶替,就在华为云上再部署一套,这时就需要测试人员检验华为云的环境是否满足系统的性能需求。 - 省钱
比如系统运营的成本,为满足某个时间段的高并发,要做基准测试,以此来评估到底要部署多少台服务器(双十一)。
1.2 不同的角度看性能
- 从黑盒测试的角度
- 数据请求经过网络发送
- 服务器前端接收处理
- 在数据库服务器获取相关数据
- 前端处理后返回数据
- 应用界接收到数据响应
- 从程序员的角度
- 结构合理性
- 数据库设计合理性
- 代码与算法
- 系统中资源的使用方式
- 系统运维角度
- 硬件资源利用率
- 何种硬件可以提高系统性能
- 系统能够支持7*24(一周的时长)的服务
- 扩展性、兼容性、最大容量、可能的瓶颈
1.3 影响性能的因素
- 硬件配置
CPU、内存、网络 - 操作系统
- 开发语言
- 用户量
- 操作方式
- 操作环境
- 使用时间
- 开发者技术水平
…
服务器挂掉的原因:
1.需求分析没到位(没有对并发数做一个相对准确的预估)- 最重要;
2.某关键时间段并发大(造成系统负载高);
3.系统架构不具有扩展性(造成宕机)。
2. 性能测试概述
2.1 性能测试定义和分类
性能测试定义
性能测试在软件的质量保证中起着重要的作用,它包括的测试内容丰富多样。中国软件评测中心将性能测试概括为三个方面:应用在客户端性能的测试、应用在网络上性能的测试和应用在服务器端性能的测试。通常情况下,三方面有效、合理的结合,可以达到对系统性能全面的分析和瓶颈的预测。
性能测试:是通过自动化测试工具模拟多种正常、峰值以及异常负载条件来对系统的各种性能指标进行测试。主要包含三层含义:
- 通常,性能测试需要借助工具来实现;
- 性能测试除了关注普通的正常的情况外,还重点关注空间和时间上的很多峰值或异常的系统运行情况;
- 性能测试借助所监控和收集的各项指标来分析系统性能。
性能测试其实就是做评估、优化和预测。
性能测试的分类
- 基准测试:先测一轮作为后面测试或者后面版本测试的基准(一般地,会把第一版第一轮的测试数据作为基准;不同版本做基准,需要进行评估,不能跨度太大)。
- 一般性能测试:验证软件在正常情况和系统条件下能够满足性能指标(基于用户行为情况和用户分布等信息,对系统是否能够达到预期服务能力进行验证)。
- 并发测试:测试多个用户同时访问同一应用,同一个模块或者数据记录时是否存在死锁或者其他问题,所以几乎所有的性能测试都会涉及到一些并发测试(通常并发操作都会加锁,死锁其实就是资源的争用)。
- 负载测试:确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统各项性能指标的变化情况。验证系统在一定压力下延长系统运行时间,直到系统性能出现“拐点”(跨过拐点,系统出现不稳定的情况,比如性能的下降)。
- 压力测试:验证系统在已经处于极限负载下或者某指标已经处于饱和状态下系统性能的表现(系统濒临崩溃,寻找系统极限值的过程),来获得系统能够提供的最大服务级别。
- 疲劳强度测试:对系统进行加压(可以是并发量,也可以是时间),测试系统出现疲劳时候的点(系统逐渐变慢的临界点。如果是时间,一般跑24h以上)。
- 稳定性测试: 验证系统在连续运行的情况下,查看系统的各项性能指标——MTBF(错误发生的平均时间间隔),是否长时间运行会出现内存泄露等问题(一般跑72h以上)。
- 容量测试:预先分析出反映软件系统应用特征的某项指标的极限值(如最大并发用户数、数据库记录数等),系统在其极限状态下没有出现任何软件故障或还能保持主要功能正常运行。容量测试还将确定测试对象在给定时间内能够持续处理的最大负载或工作量。
- 大数据量测试:主要针对对数据库有特殊要求的系统进行的测试,验证系统在使用大批量数据对系统产生压力或影响的情况下系统各种指标是否正常。
1)实时大数据量:模拟用户工作时的实时大数据量,主要目的是测试用户较多或者某些业务产生较大数据量时,系统能否稳定地运行。
2)极限状态下的测试:主要是测试系统使用一段时间即系统累积一定量的数据时,能否正常地运行业务。
3)前面两种的结合:测试系统已经累积较大数据量时,一些实时产生较大数据量的模块能否稳定地工作。 - 配置测试:验证系统在不同的软件或硬件配置的情况下,找出系统各项资源的最优分配。
- 恢复性测试(也称作可维护性测试,失效恢复测试):当软件运行故障时的恢复能力。失效恢复测试一般是对具有负载均衡的系统或者是具有备份的系统进行的,主要是为了测试当系统局部发生故障时,是否会对全局产生较大的影响,产生的影响是否在可以接受的范围内,以及用户是否能够继续使用系统(还要关注失效后,系统还能支持多少用户并发操作,以及出现这种情况,可以采用哪些应急方案来快速解决问题。具有主从备份的系统一般要做失效恢复性测试。如主库发生故障,从库自动切换为主库,主库恢复后,是保持两个主库,还是恢复一主一从等等)。
- 现网性能测试:在真实的环境下做性能测试(为了得出最真实的数据,这种类型的测试要注意一些问题对网络性能的影响,比如占用过多的带宽,影响其他业务,垃圾数据的清理等。一般做性能测试是在内网的环境下进行,·比如服务器系统相关的各种配置的测试,基本都是在局域网做,但没有办法评估网络环境的带宽等限制问题,在局域网测试可能没有问题,真实环境下就不一定,可能就会因为带宽网络的限制问题,导致用户无法访问系统,无法满足需求)。
没有必要把所有测试都做一遍,一般就是做基准测试,一般性能测试,稳定性测试;如果是负载均衡的系统或有备份的系统,就要做失效恢复性测试;如果要评估网路带宽,需要做现网性能测试。按需进行测试。
2.2 常用性能测试术语、性能测试指标
- 虚拟用户(Virtual User,简称vu):在测试环境中,Loadrunner和一些性能测试工具在物理计算机上使用Vuser来“虚拟”实际用户的操作行为。
- 并发和并发用户数:
- 并发:强调“大量用户”的“同时性”操作,该操作要求对服务器(不是客户端)产生压力;
- 并发用户数:指的是在某一时刻同时进行了对服务器产生影响的操作的用户数量(并发用户数<在线用户数<系统用户数)。注意:“系统用户数”与“在线用户数”之间的差异,“系统用户数”指的是某一个特定的系统的用户总量;“在线用户数”指的是登陆了系统或正在使用系统的用户人数。
- 响应时间:包含“请求响应时间”和“事务响应时间”。
- 请求响应时间:服务器收到用户请求到把响应内容发送出去,这段时间(运维考虑);
- 事务响应时间:处理请求对应事务的时间(开发考虑);
- 如果从用户的角度来说,响应的时间为:从请求发出到看到响应结果。这个响应时间的影响因素有很多,比如:用户的带宽,运营商,服务器,服务器的数据处理,返回的运营商,用户电脑的处理速度等;
- 响应时间=网络传输请求的时间(浏览器到服务器)+服务器处理(一层或多层)时间(比如:nginx-tomcat-redis-mysql)+网络传输响应的时间(服务器到浏览器)+页面前端解析渲染时间;
- 对外告知响应时间时,要带上TPS,即要指明在多少TPS下的响应时间(因为响应时间随访问人数变动,所以只告知响应时间是不正确的)。
- 思考时间:模拟真实用户操作而停顿的时间间隔。
- 两次请求之间的间隔时间(loadrunner中默认情况下,思考时间是0);
- 思考时间会影响到TPS。
- 点击率:一般指每秒钟用户向服务器提交的请求数(Web测试中特指HTTP请求数)。
- 每秒事务数(Transaction Per Second,TPS):指每秒钟系统能够处理的事务数量(评判系统的处理能力)。
- 一个事务里可以有一个或多个请求,比如测登录,一个事务里可能就会有多个请求;如果是测一个接口的性能,那么一个事务里就可能只有一条请求);
- TPS就是站在客户端的角度衡量服务器处理能力。
- TPS=并发用户数/响应时间。
- 吞吐量与吞吐率:用于反应客户端和服务器之间网络状态的一个指标,其能间接反应服务器承受的系统压力
- 吞吐量:在单次业务中,客户端和服务器进行的数据交互总量,受服务器性能和网络性能的影响;
- 吞吐量是衡量网络性能的实际指标,而带宽是理论指标。
- 吞吐量可以理解为TPS。
- 在LoadRunner中,这个指标是以字节数为单位来衡量网络吞吐量,而在JMeter中则是以事务数/秒为单位来衡量系统的响应能力的。大多数英文的性能测试方面的书籍或资料中,吞吐量的定义使用的是后者(事务数/秒)。
- 吞吐率:吞吐量除以传输时间,衡量服务器性能和网络性能的重要指标之一,一般可以用“请求数/秒、页面数/秒、字节数/秒”等单位衡量(“字节数/秒”最常用)。
- 吞吐量:在单次业务中,客户端和服务器进行的数据交互总量,受服务器性能和网络性能的影响;
- 性能计数器(操作系统层面,一般运维人员用的较多):性能计数器是一系列用于描述各类型服务器或者操作系统性能的指标,在进行资源监控和系统瓶颈分析中起着重要的作用。
- 资源利用率:CPU、内存、网络、IO
并发的三个条件:大量的用户,同时性操作、操作要对服务器产生压力。
类似的,物理上的共振:是指一物理系统在特定频率和波长下,比其他频率和波长以更大的振幅做振动的情形;这些特定频率和波长称之为共振频率和共振波长。在共振频率和共振波长下,很小的周期振动便可产生很大的振动,因为系统储存了动能。当阻力很小时,共振频率和共振波长大约与系统自然频率和自然波长(或称固有频率和固有波长)相等,后者是自由振荡时的频率和波长。
不同视角下的性能指标
用户视角:TPS,响应时间
开发视角:代码执行速度
运维视角:CPU、内存、网络、IO
测试视角:以上全部
3. 性能测试流程
3.1 性能测试准备
在测试前,要充分了解产品规格说明,用户行为,用户分布,运维日志,市场计划,系统架构等等,做好性能需求分析,分析从整体到局部,从表到里分析清楚,做好调优的准备。
3.2 性能测试流程
3.2.1 性能测试开展阶段
一般地,在产品开发周期中:
1.先做性能规划,功能测试通过之后,再做性能测试;
2.在技术选型的阶段做性能测试。
3.2.2 功能测试流程与性能测试流程对比
功能测试流程:需求分析–测试计划–用例编写–测试执行–输出报告
性能测试流程:需求分析–方案设计–测试计划–脚本编写–环境搭建–数据准备–执行测试–收集监控数据–分析调优–输出报告
3.2.3 性能测试流程
- 需求分析
- 产品规格:产品经理告知要做什么样的功能;
- 用户模型:用户常用功能,使用时间段,使用用户量等;
- 系统数据:基础数据和业务数据(因为性能测试需要大量的数据,如果数据量较少,那么与数据相关的 性能问题,就很难反应实际问题。造数据的原则:宁多勿少);
- 系统架构:系统架构可以说是为软件系统提供一个结构、行为和属性的高级抽象过程(比如:浏览器–>web服务器(nginx)–>应用服务器(tomcat)–>缓存(redis)–>数据库(mysql));
- 运维日志:进一步确认真实用户的数据和行为(一般系统在线上运行一段时间都会存有运维日志,从运维日志的角度,进一步了解用户数据和行为);
- 市场计划:帮助我们考虑系统性能扩展性(比如双十一,一些需要大并发的场景)。
- 项目管理计划:帮助我们明确测试点的优先级(有些哪些需要测试,测试的时间安排等)。
- 产出需求分析文档。
- 方案设计(需求是源头,方案是指引)
- 压测环境:线上/线下;
- 工具选择:LR/JMeter等(要考虑业务需求,自身能力);
- 场景设计:单场景/复杂场景(由需求分析得出)。
- 测试计划(人物,事件,起止时间等)
- 完整版:项目背景,风险说明,风险应对方案等(用word编写一个完整的性能测试计划);
- 精简版:使用工具安排测试:什么时间点,时间段,什么人,做什么事等(如:project)。
- 脚本编写
- 先了解系统:接口、功能、彼此之间的依赖关系;
- 编写脚本
- 要编写注释
- 脚本要在场景中执行通过
- 环境搭建(一般运维、开发帮忙搭建)
- 搭建环境需要的资源:比如服务器数量,配置等;
- 线下环境如何模拟线上环境(能在线上做测试最好,不能线上也要接近线上的环境);
- 线上测试
- 若线上系统还未给用户使用,可以直接线上测试(新系统,无真实用户);
- 全链路压测(已上线系统,有真实用户;比如早期阿里的全链路压测方案:首先所有流量通过网络接入层(nginx),走网关(由于压测流量有标识,网关会过滤真实流量和压测流量)、应用服务器-集群(消息中间件)、数据中间件(缓存等)、数据库(影子库,正常库)等。线上的这些流程几乎都会识别区分开压测流量和真实流量,同时也会有管理系统跟踪管理这些流量)-即要求数据隔离,不要影响到真实的业务数据和操作等。全链路压测很难推行,基本上都是一些完善的系统,对性能要求高的公司施行,且全链路压测目前基本没有代替方案。
- 全链路压测注意事项
- 压测时不能影响到线上用户;
- 测试数据不能影响线上数据库(数据的隔离性要做好);
- 系统较复杂时,要协调多团队;
- 压测操作不能影响日志统计(压测的东西不要统计到正常的日志中)。
- 全链路压测通用思路
- 压测流量要做标识;
- 所有的web服务器,应用服务器,缓存服务器、消息队列服务器、数据库服务器都要能够区分识别出压测流量和正常流量;
- 所有存储和落地的数据中(mysql,redis,rocketmq(消息队列))都要有一个影子库或影子表或者缓存区域去存储这些压测流量。
- 全链路压测注意事项
- 测试出测试机器的扩展系数(比如一台服务器能够承受100名用户并发,但二台服务器并不能承受200名用户的并发,因为会有资源的损耗;一般扩展系统1.8就是做的比较好的,比较差的1.5~1.6)-如果线下和线上环境差异过大,那么测出的扩展系数就毫无意义。
- 数据准备
- 准备的数据量(需求分析得出)
- 准备数据(如JMeter跑接口生成数据、直接在MySQL跑数据,用自动生成数据的工具、线上的数据导入(要脱密))。
- 执行测试(设置好场景,执行脚本);
- 收集和监控数据(监控收集数据,为数据分析调优做准备);
- 分析调优(<执行测试-收集监控数据-分析调优>是反复的过程,直到调优到满足需求为止);
- 输出报告(针对什么人,写什么样的报告,是写的官方还是通俗易懂)。
性能测试的重点与难点:需求分析、诊断和调优。
性能测试流程如下图:
- 性能需求分析
性能需求中要求有明确的指标,它是用来判断未来结果是否准确的依据(预期结果)。
性能测试需求提出的依据:
1)客户方提出
2)根据历史数据分析
3)需求分析与定位
4)参考历史项目或者其他同行业项目
5)参考其他数据资料
eg:
响应速度:API请求的平均响应时间应低于1s,WEB首页打开速度5s以下,web登录速度15s以下;
服务支持50万用户同时在线;
某个接口支持200个用户同时调用(平均3s调用一次);
计费请求成功率达到99.999%以上;
在100个并发用户的高峰期,邮箱的基本功能,处理能力至少达到10TPS;
系统能在高于实际系统运行压力1倍的情况下,稳定运行12h… - 测试场景设计
如下图所示:
- 测试结果是否通过的标准(仅供参考,一般企业会自己制定标准)
如下表所示:
- 性能调优需要掌握的技能
eg:
系统要求能够支持200w用户同时在线,性能测试分析如下图所示:
性能测试中的重点和难点
- 需求分析
- 场景设计
- 性能诊断调优
- 环境搭建和模拟
3.3 性能测试的专业分析
从专业角度分析,性能测试需要做:
- 服务器硬件性能
- 根据需求和历史数据制定性能目标
- 建立性能通过模型
- 对开发代码框架和硬件框架进行性能分析
- 针对开发发布版本的基准测试
- 对软件进行性能验收和稳定性测试
- 生产环境的配置和优化
- 指定性能测试测试用例
- 指定性能测试场景设计
- 特定性能分析
3.4 性能测试用例设计
注意:功能测试做完后,才能做性能测试,而且性能测试中不再做反向数据的验证。
用例中术语:
- 集合点:所有用户集合在一起,进行并发;
- 事务:用户的操作行为的总称,用来衡量TPS,事务成功率的基础。
eg:
性能测试用例案例:
性能测试用例中的测试目的开始变得复杂,不再是唯一的目的,可能会包含很多测试要点。
预期结果:性能测试执行后,结果判断的标准。
4. 所需技能和工具选择
4.1 所需技能
4.2 测试工具选择
性能测试工具
前面两个工具常用
- HP公司的Loadrunner
- Apache JMeter(开源)
- Grinder(开源)
- CompuWare公司的QALoad
- Microsoft公司的WAS
- RadView公司的WebLoad
- IBM公司的RPT
测试工具的选择要考虑的层面:
- 专业、稳定、高效,工业级的性能负载工具(比如Load runner);
- 简单且容易上手,在测试脚本上不用花太多的时间;
- 有技术支持,文档完善,不用再软件使用的疑难问题上花费太多的时间;
- 性价比与技术产出比
商业工具与自研/开源工具特点对比
自研/开源工具 | 商业工具 |
---|---|
能够开发出最适合的测试工具 | 依赖于工具本身提供的特性,较难扩展 |
易于学习和使用 | 依赖于工具的易用性和所提供的文档 |
工具的稳定性和可靠性不足 | 稳定性和可靠性有一定的保证 |
可形成组织特有的测试工具体系 | 很难与其他产品集成 |
5. 性能理论模型
5.1 理发店模型
假设
- 理发店共有理发师3名(系统资源,服务器);
- 每位理发师理一个人的头发需要1h(处理时间);
- 顾客到理发店理发,所能容忍的时间是(等待时间+剪发时间)3h(响应时间),即等待时间最多2h;
- 响应时间(等待时间+剪发时间)超过3h,顾客可能就会直接走人(不再请求或重新请求)。
场景
- 场景1:当理发店有2名顾客时,有2名理发师进行理发服务,这2名顾客均花费1h(存在资源浪费)。
- 服务完2名顾客离开,需要1h;
- 存在资源浪费(有一名理发师空闲)。
- 场景2:当理发店有3名顾客时,有3名理发师进行理发服务,这3名顾客均花费1h。
- 服务完3名顾客离开,需要1h;
- 3名顾客为最佳并发用户数(资源得到了充分利用)。
- 场景3:当理发店有4名顾客时,有3名理发师进行理发服务,剩余1名顾客需要等待1h才能够进行理发。
- 服务完4名顾客离开,需要2h。
- 超过3名顾客,其中3个人需1h,一人需2h(等待1h+理发1h),这说明没有绝对的并发。
- 场景4:当理发店有7名顾客时,有3名理发师进行理发服务,剩余3名顾客需要等待1h、1名顾客需要等待2h才能理发。
- 服务完7名顾客离开,需要3h。
- 场景5:当理发店有9名顾客时,有3名理发师进行理发服务,剩余3名顾客需要等待1h、3名顾客需要等待2h才能理发。
- 服务完9名顾客离开,需要3h。
- 响应时间3h为最大忍耐限度,响应时间最低要求;
- 9名顾客为最大并发用户数(最大边界值),超过会出现顾客离开的情况。
- 场景6:当理发店有10名顾客时,有3名理发师进行理发服务,剩余3名顾客需要等待1h、3名顾客需要等待2h才能理发、1名顾客需要等待3h。
- 1名顾客超过忍受时间极限,离开理发店,放弃理发;
- 为保证用户的正常访问,超过最大并发用户数,系统可提醒拒绝访问或超时。
5.2 性能测试拐点模型
拐点模型
- 响应时间
- 随压力增大,响应时间基本保持不变,曲线趋于平稳,图像几乎呈平滑的直线(0 ~ 最佳并发用户数);
- 超过最佳并发用户数,随着压力增大,曲线呈上升趋势,响应时间开始明显增加(最佳并发用户数 ~ 最大并发用户数);
- 超过最大并发用户数,随着压力增大,曲线上升趋势变得陡峭,响应时间成倍增长(最大并发用户数 ~ ∞)。
- 吞吐量
- 随压力增大,吞吐量逐渐增大,曲线呈上升趋势(0 ~ 最佳并发用户数);
- 超过最佳并发用户数,吞吐量继续增大,直到到达最大吞吐量(曲线最高点,此时服务器处理能力达到瓶颈),然后吞吐量开始下降(最佳并发用户数 ~ 最大并发用户数);
- 超过最大并发用户数,随着压力增大,曲线呈断崖式下降,服务器濒临崩溃。
- 资源利用率
- 随压力增大,资源利用率逐渐增大,曲线呈上升趋势(0 ~ 最佳并发用户数);
- 超过最佳并发用户数,随着压力增大,曲线趋于平稳,图像几乎呈平滑的直线,资源利用率达到饱和状态( 最佳并发用户数 ~ ∞)。
资源利用:软硬件资源;
Light Load(较轻的压力)、Heavy Load(较重的压力)和Buckle Zone(用户无法忍受并放弃请求);
模型与用户联系
- 系统的负载=最佳并发用户数
- 系统的整体效率最高,没有资源浪费,用户不需要等待。
- 最佳并发用户数<系统负载<最大并发用户数
- 系统可以继续正常工作,但由于用户的等待时间延长,满意度开始下降。
- 系统负载>最大并发用户数
- 导致有些用户无法忍受等待时间而放弃访问;
- 随着并发人数的继续增加,系统展现疲态,工作效率降低,响应时长成倍增加。
综上,对于一个系统:
- 系统平均负载<系统最佳并发用户数
- 因为如果[系统平均负载>最佳并发用户数],长此以往,系统风评下降。
- 扩展:在做系统的可靠性或稳定性测试的时候,要保持[系统平均负载≤最佳并发用户数]。
- 系统需要承受的峰值负载<系统最大并发用户数
- 系统对用户请求的响应速度,就决定着用户对系统性能的评价。
- “好的性能”意味着更大的最佳并发用户数和最大并发用户数。
6. MySQL
6.1 MySQL进行事务管理
事务:指逻辑上的一组操作,组成这组操作的单元要么全部成功,要么全部失败。
事务的作用:保证一组操作全部成功或全部失败。
比如执行SQL语句,前一句操作成功,而后一句操作失败,那么这两句SQL语句全部执行失败。事务的作用就在于保证一组操作全部成功或全部失败。
6.1.1 自动事务(MySQL默认)
MySQL自动事务管理:MySQL默认进行自动事务管理(自动开启事务,自动提交事务),一条SQL语句就是一个事务。
注意:自动事务管理就会有弊端,比如:zhangsan向lisi转账100.
update account set money = money - 100 where name = 'zhangsan';
update account set money = money + 100 where name = 'lisi';
如果前一句执行成功了,而后一句未执行成功,由于自动事务管理,前一句已经自动提交了,而后一句因为异常未成功执行,对于这组操作来说就会出现问题。所以这时候就显得手动事务管理十分的重要。
6.1.2 手动事务管理
方式1:
- 手动开启事务:
start transaction;
- 手动提交事务:
commit;
- 手动回滚事务:
rollback;
eg:
出现异常情况:
start transaction;
update account set money = money - 100 where name = 'zhangsan';
-- 此时出现异常
rollback; -- 回滚:取消前面的SQL语句操作
update account set money = money + 100 where name = 'lisi';
未出现异常情况:
start transaction;
update account set money = money - 100 where name = 'zhangsan';
update account set money = money + 100 where name = 'lisi';
commit;
事务的原理
方式2:
设置MySQL中的自动提交的参数
-- 查看MySQL中事务是否是自动提交
show variables like '%commit%';
-- 设置自动提交的参数为OFF
set autocommit = 0; -- 0:OFF 1:ON
6.1.3 回滚点
如果有一组操作,前面的操作成功,后面的操作失败,但这里的场景不需要将前面的操作取消,那么设置回滚点就显得的十分必要。即在当前成功的位置设置一个回滚点,供后续操作失败后回滚到该位置,而不是返回所有操作。
设置回滚点:savepoint 名字;
回到回滚点:rollback to 名字;
eg:
注意:MySQL要支持事务需注意以下条件
1.Mysql数据库引擎InnoDB要支持事务show engines;
2.数据库表的引擎应是innoDBshow table status from test where name="account";
发现当前数据库表引擎为默认的MylSAM
更改account数据库表引擎为innoDBalter table account engine = innodb;
-- zhangsan初始金钱1000
start transaction;
update account set money = money - 10 where name = "zhangsan";
update account set money = money - 10 where name = "zhangsan";
savepoint mark; -- 设置回滚点
update account set money = money - 10 where name = "zhangsan";
rollback to mark; -- 发生异常,返回回滚点
update account set money = money - 20 where name = "zhangsan"; -- 继续执行
commit; -- 结果:1000-10-10-20=960
应用场景:回滚点经常应用与插入大量数据的时候,当插入数据中间出错时,只回滚到回滚点,不用全部回滚,节省了资源与时间。
6.2 事务特性和隔离级别
6.2.1 事务特性
- 原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生;(一组操作不能分开)
- 一致性(Consistency):事务前后数据的完整性必须保持一致;
- 持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响;
- 隔离性(Isolation):指多个用户并发操作数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离(事务之间互不干扰)。
eg:
原子性eg:如zhangsan初始1000,lisi初始1000;zhangsan给lisi转100,要么转账成功zhangsan 900,lisi 1100;要么转账不成功zhangsan 1000,lisi 1000。
一致性eg:如zhangsan初始1000,lisi初始1000,加和2000;zhangsan给lisi转100,要么转账成功zhangsan 900,lisi 1100,加和2000;要么转账不成功zhangsan 1000,lisi 1000,加和2000。
若不考虑隔离性所带来的后果(并发操作,多个用户同时访问同一个数据,可能会引发并发访问的问题)
并发访问的问题 | 含义 |
---|---|
脏读 | 一个事务读取到了另一个事务中尚未提交的数据。 |
不可重复读 | 一个事务中两次读取的数据内容不一致,要求的时一个事务中多次读取时数据是一致的(事务update时引发的问题)。 |
幻读 | 一个事务中两次读取的数据的数量不一致,要求在一个事务多次读取的数据的数量是一致的(事务insert或delete时引发的问题)。 |
事务在操作时的理想状态:所有事务之间保持隔离,互不影响。
6.2.2 事务隔离级别
为解决事务并发所可能导致的问题,就引入了事务隔离级别,可以通过设置事务隔离级别解决读的问题。
事务隔离级别
级别 | 名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 |
---|---|---|---|---|---|---|
1 | 读未提交 | read uncommitted | 是 | 是 | 是 | |
2 | 读已提交 | read committed | 否 | 是 | 是 | Oracle |
3 | 可重复读 | repeatable read | 否 | 否 | 是 | MySQL |
4 | 串行化 | serializable | 否 | 否 | 否 |
隔离级别越高,安全性越高,性能(效率越差)。
一般情况下,不会用到串行化,因为效率太低。
查询MySQL当前事务隔离级别
select @@tx_isolation;
设置MySQL事务隔离级别
-- 隔离级别:read uncommitted、read committed、repeatable read、serializable
set session transaction isolation level 隔离级别;
eg:
-- 设置隔离级别等级一
set session transaction isolation level read uncommitted;
select @@tx_isolation; -- MySQL8以前的版本
select @@transaction_isolation; -- MySQL8以后的版本
开启两个数据库连接,分别执行事务A和事务B
此时事务B更新zhangsan的金钱-900
此时事务A查询账户发现出现了“脏读”的情况
将事务A和事务B都提交
更改隔离级别为二级read committed
开启事务A和事务B…发现解决了“脏读”的问题
将事务B提交,事务A再次查询发现存在“不可重复读”的问题
将事务A提交
更改隔离级别为三级repeatable read
开启事务A和事务B…发现解决了“不可重复读”的问题
事务A提交
“幻读”很难显示出效果,这里只演示设置四级隔离级别后,事务A和事务B之间的串行关系(就类似“锁”一样)
设置隔离级别为四级serializable
开启事务A和事务B…只有当事务B提交后,账户数量变为3
6.3 数据的备份和还原
MySQL数据库备份 mysqldump -u 用户名 -p 数据库>文件路径 密码
MySQL数据库还原
source 导入文件路径
eg: 备份test数据库,test数据库下有account表
数据备份,保存在桌面的test_data.sql中
mysqldump -uroot -p account>C:/Users/hyh/Desktop/test_data.sql 密码
备份成功
数据还原
create database test02;
use test02;
source C:/Users/hyh/Desktop/test_data.sql