mysql事务的理解学习, 面试不问索引原理就是事务原理

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: mysql事务的理解学习, 面试不问索引原理就是事务原理

事务理解

事务组成

  • 简单的来说事务可以由一条简单的sql语句组成,也可以由一组复杂的sql语句组成(事务是一个程序逻辑单元)

事务特征

在数据库针对事务进行提交的时候,要么是所有的修改都保存,要么所有的修改都丢弃  (原子性,要么整个事务全部完成,要么整个事务全部丢弃)


事务是访问并更新数据库各种数据项的一个程序执行单元


mysql的innodb 引擎是支持事务的, myisam 是不支持事务的, innodb中每一条sql语句都是事务;我们如果想要取消自动提交事务,可以通过设置 set autocommit = 0; 设置当前会话手动提交事务


常见事务的控制语句

-- 显示的开启事务
start transaction | begin;
-- 提交事务,并且对于当前数据库所作的操作修改做持久化
commit;
-- 回滚事务,结束用户的事务,并撤销正在进行的所有未提交的修改
rollback;
-- 创建一个保存点,一个事务可以有多个保存点
savepoint identifier
-- 删除一个保存点
release savepoint identifier
-- 事务回滚到保存点
rollback to [savepoint] identifier

事务的ACID特征

原子性 (可借助多线程对全局数据做写入操作哪里的理解)  绑定操作单元


浅层理解:这个好理解, 就是说事务一定是一个原子操作序列单元,所有操作在一次执行过程中仅仅只会允许两种状态                ---   要么全部执行成功  要么全部执行失败   绑定在一个事务中的所有操作


深入理解:事务操作要么都做(提交),要么都不做(回滚);事务是访问并更新数据库各种数据项的一个程 序执行单元,是不可分割的工作单位;通过undolog来实现回滚操作。undolog记录的是事务每步具体操作,当回滚时,回放事务具体操作的逆运算;(回滚原理,沿着undolog往回恢复操作之前的样子)


隔离性


一个事务的执行不能被其他事务干扰。


要解释隔离性: 首先理解事务并发,我们的数据库的用户是很多的,是可以并发执行事务的,隔离性指的就是并发的事务是相互隔离,互不干扰的。 也就是说不同的事务并发操作相同的数据时候,每一个事务都是存在自己独立完整的数据空间的


深入理解原理:事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离,也就是事务提交前对其他事务都不可见;通过 MVCC 和 锁来实现;MVCC 时多版本并发控制,主要解决一致性非锁定读,通过记录和获取行版本,而不是使用锁来限制读操作,从而实现高效并发读性能。锁用来处理 并发 DML 操作;数据库中提供粒度锁的策略,针对表(聚集索引B+树)、页(聚集索引B+树叶 子节点)、行(叶子节点当中某一段记录行)三种粒度加锁

MVCC性能更优, 避免了加行锁读操作,避免了锁等待


持久性  (先写日志再写磁盘, 高效)


事务一旦提交,他对数据的改动是持久性的,事务一旦提交,相关的数据就应该从游离态或瞬时态变成持久态。


redo log是InnoDB引擎特有的日志模块,记录的是:在某个数据页上做了什么修改;


当MySQL执行一条更新语句的时候,InnoDB引擎会把记录先写到redo log文件中,并更新内存。此时这条更新操作就算完成了,但是并没有将数据的更新持久化的磁盘,InnoDB引擎会在一个合适的时机将数据的更新操作持久化到磁盘。


事务提交后,事务DML操作将会持久化(写入redolog磁盘文件 哪一个页 页偏移值 具体数据); 即使发生宕机等故障,数据库也能将数据恢复。redo log记录的是物理日志; (意思就是说事务的所有的DML操作都会写入redo log 磁盘文件, 将操作的位置和具体操作都记录在redo log日志中, 所以就算是发生了宕机等现象也是可以还原的)


一致性  (是一种状态, 无论是回滚还是提交, 数据完整性不被破坏)


指的是数据库操作前后需要保持数据的完整性和一致性,  事务的执行是导致数据库从一种一致性状态转换为另外一种一致性状态,也就是说事务执行前后,数据库的完整性约束没有被破坏.       (eg : A账户向B账户转账500元,不可能说A账户减少500元,B账户却没有增加500元)


一致性由原子性、隔离性以 及持久性共同来维护的。

事务的并发异常

脏读

  • 事务A可以读取到另外一个事务B还没有提交的数据这个事务A读取到的未提交数据就是所谓的脏读数据,要演示读取到脏读数据, 首先我们需要将隔离等级设置为 read uncommitted 读未提交
  • 演示脏读

不可重复读  (读 + 读,结果不一样)


事务(A) 可以读到另外一个事务(B)中提交的数据;通常发生在一个事务中两次读到的数据是不一样的情况; 不可重复读在隔离级别 READ COMMITTED 存在。一般而言,不可重复读的问题是可以接受的,因为读到已经提交的数据,一般不会带来很大的问题,所以很多厂商(如Oracle、 SQL Server)默认隔离级别就是READ COMMITTED


A 事务 第一次读 , B事务还没有commit , A 事务第二次读, B事务进行了commit, 两次读结果就不会一致

幻读        (读 + 写, 以为自己读到了,去对其进行写操作,实际不存在)


事务中一次读操作不能支撑接下来的业务逻辑;通常发生在一个事务中一次读判断接下来写操作失败的情况;   例如:以name为唯一键的表,一个事务中查询 select * from t where name = 'mark'; 不存在,接下来 insert into t(name) values ('mark'); 出现错误,此时另外一个 事务也执行了 insert 操作;幻读在隔离级别 repeatable read 及以下存在;但是可以在 repeatable read 级别下通过读加锁(使用共享锁)解决;


简单的举出一个幻读的例子,就是A事务刚刚查询一个记录不存在,接下来准备做insert操作,这个时候另外的B事务插入了这个记录,并提交,此时相当于是刚刚的记录查询是虚幻的,不是真实的,也称为幻读  

解决办法1:  查询操作的时候加上一把共享读锁, 读锁,间隙锁,锁住之后别的事务就不能对齐进行插入操作了, 查询的时候加上共享锁,事务B 就无法完成插入操作, 这样就避免了幻读现象了   (mysql中的共享锁就相当于我们学操作系统时候的写锁)


解决办法2: 直接修改事务的隔离级别为顺序读: serializable,  串行之后会读操作也会自动加上共享锁 share in mode,但是基本不提倡,效率太低下了,锁等待,性能下降的可怕.

事务隔离级别

  • 隔离级别的浅显知道

事务隔离等级越高,会越来越安全, 但是效率会变得越来越低,并发性也越来越差


默认等级一般是读已提交或者是可重复读


ISO和ANIS SQL标准制定了四种事务隔离级别的标准,各数据库厂商在正确性和性能之间做了妥 协,并没有严格遵循这些标准;MySQL innodb默认支持的隔离级别是 REPEATABLE READ;    


隔离级别的底层实现 (mvcc  + 各种锁)    mvcc + 各种锁都是为了保证在并发执行下事务之间的隔离性, 原子性 等性质

READ UNCOMMITTED 读未提交;该级别下读不加锁,写加排他锁,写锁在事务提交或回滚后释放锁       (读未提交,这个级别下读是不会加锁的,也没有mvcc)


READ COMMITTED  读已提交;  该级别下读不会自动加锁, 而是采取的mvcc(多版本并发控制),  也就是提供一致性非锁定读,  此时读取操作 读取历史快照数据;该隔离级别下读取历史版本的最新数据,所以读取的是已提交的数据;      (正是因为读的是历史版本最新的数据, 也就是当前已提交的数据, 所以不支持重复读,因为有其他事务做新的提交, 该事务重复再读取结果会和提交前不一致)

REPEATABLE READ 可重复读;该级别下也支持 MVCC,此时读取操作读取事务开始时的版本数据


也就是说 repeatable read 如何支持可重复读, 不管你提交多少新的版本, 我永远只是读取开启事务的第一版, 也就是我最初的一版历史数据, 其他事务提交的最新版历史快照数据我不会理睬.      (      因为一直读取第一版数据, 自然不会因为最新版数据引起重复读数据不一致的问题, 这个就是 reapeatable read, 所以现在懂了塞,为啥它可以支持重复读数据一致     )


SERIALIZABLE 可串行化;该级别下给读加了共享锁 (S锁);所以事务都是串行化的执行;此时隔离级别最严苛;

小总结

首先本章主要学习事务的定义,了解事务的重要性质, 初步认识锁 + mvcc 支持并发多事务执行操做的原因  (以及认识各种隔离级别的底层实现)


啥叫事务:一条简单的sql语句 或者 是 多条复杂的sql语句的集合


事务需要保证哪些性质        :  


原子性: undo log  回滚操作保证所有的sql语句要么全部执行成功,要么全部执行失败


隔离性:   mvcc + 锁 保证 读写操作 各个事务之间相互隔离,互不干扰,  写操作肯定要加x锁, 读操作  分版本,


read uncommitted 不会加锁也没有mvcc  


read committed 存在mvcc多版本并发控制,   可能出现幻读现象,可以s共享锁避免, 读最新版本数据,存在不可重复读问题,  

             

repeatable read  读取最老版本的数据 避免重复读数据不一致的问题, 但是也可能出现幻读, 解决办法还是加s共享锁


serializable: 顺序读,读操作自动s锁, 绝对安全,但是并发性是最差的    

持久化:使用redo log 支持持久化, 对于mysql数据的修改物理地址 +  如何修改做日志记录,  就算是宕机了也可以利用 redo log 日志进行恢复


一致性 : 保证事务前后数据的完整性,从一种一致性状态转换为另外一种一致性状态, 一致性的保证依赖的是上述三种性质


read committed 读最新版本数据会出现 不可重复读的问题  (读取的数据是其他事务提交前和提交后的不同结果)


repeatable read : 可重复读,读历史快照数据的第一版数据,避免重复读结果不一致,但是可能出现幻读的现象,幻读,读 + 写 读完根据读结果进行 update 操作。问题,刚读完,其他事务进行了update + 提交。此刻之前select的结果已然是不正确了,之前读的数据就是幻读数据了   (如何避免,加上 s锁)


留个后文,mysql各种锁的详解,锁----》 事务至关重要


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
10天前
|
关系型数据库 MySQL 索引
mysql 分析5语句的优化--索引添加删除
mysql 分析5语句的优化--索引添加删除
11 0
|
16天前
|
SQL 关系型数据库 MySQL
轻松入门MySQL:保障数据完整性,MySQL事务在进销存管理系统中的应用(12)
轻松入门MySQL:保障数据完整性,MySQL事务在进销存管理系统中的应用(12)
|
16天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
|
10天前
|
SQL 缓存 关系型数据库
mysql性能优化-慢查询分析、优化索引和配置
mysql性能优化-慢查询分析、优化索引和配置
76 0
|
16天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
9天前
|
存储 SQL 关系型数据库
【MySQL实战笔记】03.事务隔离:为什么你改了我还看不见?-02
【4月更文挑战第7天】数据库通过视图实现事务隔离,不同隔离级别如读未提交、读已提交、可重复读和串行化采用不同策略。以可重复读为例,MySQL使用多版本并发控制(MVCC),每个事务有其独立的视图。回滚日志在无更早视图时被删除。长事务可能导致大量存储占用,应避免。事务启动可显式用`begin`或设置`autocommit=0`,但后者可能意外开启长事务。建议使用`autocommit=1`并显式管理事务,若需减少交互,可使用`commit work and chain`。
28 5
|
21天前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
38 1
|
2月前
|
存储 关系型数据库 MySQL
2024年Java秋招面试必看的 | MySQL调优面试题
随着系统用户量的不断增加,MySQL 索引的重要性不言而喻,对于后端工程师,只有在了解索引及其优化的规则,并应用于实际工作中后,才能不断的提升系统性能,开发出高性能、高并发和高可用的系统。 今天小编首先会跟大家分享一下MySQL 索引中的各种概念,然后介绍优化索引的若干条规则,最后利用这些规则,针对面试中常考的知识点,做详细的实例分析。
238 0
2024年Java秋招面试必看的 | MySQL调优面试题
|
2月前
|
存储 算法 Java
铁子,你还记得这些吗----Java基础【拓展面试常问题型】
铁子,你还记得这些吗----Java基础【拓展面试常问题型】
45 1
|
2月前
|
NoSQL Java 关系型数据库
凭借Java开发进阶面试秘籍(核心版)逆流而上
最近参加了面试或者身边有朋友在面试的兄弟有没有发现,现在的面试不仅会问八股文,还会考察框架、项目实战、算法数据结构等等,需要准备的越来越多。 其实面试的时候,并不是要求你所有的知识点都会,而是关键的问题答到点子上!这份《Java 开发进阶面试秘籍(核心版)》由 P8 面试官整体把控,目前已经更新了 30 万字! 资料中涵盖了一线大厂、中小厂面试真题,毕竟真题都是技术领域最经典的基础知识和经验沉淀的汇总,非常有必要学习掌握!双重 buff 叠加,offer 接到手软~ 点击此处取,这可能是你到目前为止领取的最具含金量的一份资料! 整套资料涵盖:Spring、Spring