前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试官:了解数据库事务吗?出门右转不用关门(已升级自动门),只要会CRUD的!

面试官:了解数据库事务吗?出门右转不用关门(已升级自动门),只要会CRUD的!

作者头像
Liusy
发布2021-02-01 10:58:44
4930
发布2021-02-01 10:58:44
举报
文章被收录于专栏:Liusy01Liusy01

前言

上一篇说了如何查看MySQL的执行计划,今天就来看一下数据库的事务相关的知识点。

面试官在数据库这方面最常问的除了sql优化,还有数据库事务、存储引擎等相关知识。上期有人说没有自动门,所以这一期我特地造了自动门,这门没有四五块造不下来。

注意:只是CRUD的搬砖工就不需要看了,看了也忘了,只需要拉到最后,点赞、在看、分享,一键三连然后收藏起来就行了。

什么是事务

事务是指是程序中一系列严密的逻辑操作,而且所有操作必须全部成功完成,否则在每个操作中所作的所有更改都会被撤消。

通俗点说就是要么一起活,要么一起死。

事务特性

事务特性就是普通都知道的ACID,那么什么是ACID,估计有些货跟我之前一样,只知道这个词,不知道每个字母代表的是什么,这次就给翻译翻译什么叫TMD惊喜(不,说错了,是字母),我还特地下了一个有道词典,浪费了几十M的流量。

A:Atomicity原子性

所谓原子性就是说事务是一个最小的单元,跟原子一样不可再分割。一个事务中的所有操作要么全部成功,要么全部失败,通过WAL(Write Ahead Log)实现。(HBASE也应用了这个技术)

I:Isolation隔离性

一个事务在操作还未结束之前,对其他事务是不可见的,即一个事务内部的操作及使用的数据对其他的并发事务是隔离的。锁和多版本控制就符合隔离性。

类似与现在的共享文档:我在编辑文档未保存之前其他人是不可见的。

D:Durability持久性

一旦事务提交,其所做的修改就会永久保存到数据库中。

人也要学会持久,老子没开车。比如健身,深蹲蹲一半怎么行。

C:Consistency一致性

数据库总是从一个一致性的状态转换到另外一个一致性的状态,也就是说在某个时间是A,另一个时间是B。

所有事务对一个数据的读取结果都是相同的,这是由原子性、隔离性、持久性共同保证的结果。

数据的完整性是通过其他三个特性来保证的,包括原子性、隔离性、持久性,而这三个特性,又是通过 Redo/Undo 来保证的,为了保证数据的完整性,提出来三个特性,这三个特性又是由同一个技术来实现的,所以理解 Redo/Undo 才能理解数据库的本质。

隔离级别

READ UNCOMMITTED 未提交读

事务所做的修改,即使未提交,对其他事务也是可见的。事务可以读取未提交的数据,也称为脏读。

也就是说能看见另一个人正在编辑的内容是什么,毫无隐私可言。

READ COMMITTED 提交读,也称不可重复读

一个事务从开始直到提交之前,所作的修改对其他事务是不可见的。也称为不可重复读,因为执行多次一样的查询,可能得到不一样的结果。

跟未提交读正好相反,我只有保存了文档,你才能看得见。

REPEATABLE READ 可重复读

同一个事务中多次读取同样的记录的结果是一样的。可能导致幻读,在多次读取间隙中,可能有其它事务插入新的记录,就会出现幻读。

SERIALIZABLE 可串行化

最高隔离级别,强制事务串行执行,避免了幻读的问题。

也就是事务必须一个一个排队执行,没有插队的情况。

并发事务问题
脏读:

一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象的叫作"脏读"(Dirty Reads)。

所谓脏读,就是说我没提交别人都能看得到事务,那么后面我删除掉编辑的内容的话他没看,别人还是以为我编辑了内容。

不可重复读

一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫作“ 不可重复读”(Non-Repeatable Reads)。

幻读

一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”(Phantom Reads)。

「注意」

不可重复读和幻读看起来很像,其实是有差别的。

不可重复读重点在于 UPDATA 和 DELETE,而幻读的重点在于 INSERT

隔离级别

脏读

不可重复读

幻读

未提交读

可能

可能

可能

已提交读

不可能

可能

可能

可重复读

不可能

不可能

可能(通过间隙锁解决)

可串行化

不可能

不可能

不可能

MVVC多版本控制

MVCC(Multi-Version Concurrency Control),行级锁的一个变种,在很多情况下避免了加锁操作,开销更低。

通过保存数据在某个时间点的快照来实现。即是不管执行多长时间,每个事务看到的数据都是一致的。

根据事务开始时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

其实就是在高并发的访问状态下,对数据进行多版本控制,并通过事务的可见性来保证事务能看到自己应该看到的数据版本。

「那个多版本是如何生成的呢?」

每一次对数据库的修改,都会在 Undo 日志中记录当前修改记录的事务号及修改前数据状态的存储地址(即 ROLL_PTR),以便在必要的时候可以回滚到老的数据版本。

InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。两列,一个保存了行的创建时间,一个保存了行的过期时间(或删除时间),存储的并不是实际的时间值,而是系统版本号。每开始一个事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。

MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现「提交读」「可重复读」这两种隔离级别。而未提交读隔离级别总是读取最新的数据行,无需使用 MVCC。可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。

快照读与当前读

在 MVCC 并发控制中,读操作可以分为两类: 快照读(Snapshot Read)与当前读 (Current Read)。

「快照读」:读取的是记录的可见版本(有可能是历史版本),不用加锁。

「当前读」:读取的是记录的最新版本,并且当前读返回的记录,都会加锁,保证其他事务不会再并发修改这条记录。

注意:MVCC 只在 Read Commited 和 Repeatable Read 两种隔离级别下工作。

「如何区分快照读和当前读呢?」

快照读:简单的 select 操作,属于快照读,不需要加锁。

当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Liusy01 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是事务
  • 事务特性
    • A:Atomicity原子性
      • I:Isolation隔离性
        • D:Durability持久性
          • C:Consistency一致性
          • 隔离级别
            • READ UNCOMMITTED 未提交读
              • READ COMMITTED 提交读,也称不可重复读
                • REPEATABLE READ 可重复读
                  • SERIALIZABLE 可串行化
                    • 并发事务问题
                    • MVVC多版本控制
                      • 快照读与当前读
                      相关产品与服务
                      数据库
                      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档