前言
这段时间也一直在学习Netty
相关知识,因为涉及知识点比较多,也走了不少弯路。目前网上关于Netty学习资料玲琅满目,不知如何下手,其实大家都是一样的,学习方法和技巧都是总结出来的,我们在没有找到很好的方法之前不如按部就班先从基础开始,一般从总分总的渐进方式,既观森林,又见草木。
Netty
是一款提供异步的、事件驱动的网络应用程序框架和工具,是基于NIO
客户端、服务器端的编程框架。所以这里我们先以NIO
和依赖相关的基础铺垫来进行剖析讲解,从而作为Netty
学习之旅的一个开端。
正文
谈到 MYSQL 的事物, 相信大家对这几个概念都不会陌生:
- 四大特性:ACID
- 并发问题
- 脏读
- 不可重复读
- 幻读
- 隔离级别
- Read Uncommitted(读未提交)
- Read Committed(读提交)
- Repeatable Read(可重读)
- Serializable(可串行化)
下面的思维导图可能更表达得清晰😏
MySQL 的默认事物隔离级别是 RR (Repeatable Read)
,可重复读级别是能够解决脏读、不可重复读的这两个事物并发问题的,但是幻读的问题仍会存在,如果使用Serializable
的隔离级别,对于高并发的业务来说是不实际的。那么 MySQL 是如何解决幻读这个棘手的问题呢?
没错,MySQL 通过MVCC
(多版本并发控制)和Gap Lock
(间隙锁)这两个机制解决了幻读的问题~
那么这两种方式具体又是如何实现的呢?
这里我们先讲一下 MySQL 的**"读"的区别**。因为在事物隔离级别中的**“读”**,分为快照读(snapshot read)
和当前读(current read)
1. 当前读(current read)
select…lock in share mode (共享读锁) select…for update update , delete , insert
读取的是最新的数据,并且对读取的记录加锁,阻塞其他事物对当前事物查询数据的修改和插入,从而解决幻读。
实现方式:Next-key Locks(临键锁)
官方对临键锁的定义是:
A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.
简单来说就是 临键锁 = 行记录锁 + 间隙锁
行锁、间隙锁这个锁的概念,下文会介绍。所以这里我们只要知道的是,对于事物的当前读模式,是通过 Gap-Key-Locks 解决的。
2. 快照读(snapshot read)
select * from table
单纯的 select 操作
Read Committed 隔离级别:每次select都生成一个快照读。
Read Repeatable 隔离级别:开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读。
实现方式:undolog 和 MVCC
undolog 用于数据的撤回操作,它记录了修改的反向操作,比如,插入对应删除,修改对应修改为原来的数据,通过undo log 可以实现事务回滚,并且可以根据 undo log 回溯到某个特定的版本的数据。
MVCC 就是上文提到的多版本并发控制。
实现方式
MVCC
MVCC 只是工作在两种事务级别底下:
- Read Committed
- Repeatable Read
MVCC 每行记录后面保存三个隐藏的列,其中其主要作用的有两列
DB_TRX_ID: 记录行数据创建时的事物版本号。每开启一个事物,事物版本号都会递增。
DB_ROLL_PTR: 记录行数据何时过期(或者被删除)。指向前一个版本的 undolog 记录,组成 undo 链表。如果更新了行,则撤消日志记录包含在更新行之前重建行内容所需的信息。
-
INSERT
插入数据时, DB_TRX_ID 记录的是当前新增数据的事物版本号
-
DELETE
删除数据时,DB_ROLL_PTR 记录的是当前操作删除的事物版本号
-
UPDATE
-
更新数据时,插入一条新的数据,DB_TRX_ID 记录的是当前更新数据的事物版本号
-
将旧数据的 DB_ROLL_PTR 值更新为当前更新数据的事物版本号
-
-
SELECT
查询规则如下:
-
查找数据行版本号早于当前事务版本号的数据行记录,也就是说(当前的查询的事物版本号 >=
DB_TRX_ID
中的值)这样就能确保事物读取的数据,要么是当前事物已经存在的,要么是当前事物所操作过的。
-
查找删除版本号要么为NULL,要么大于当前事务版本号的记录。也就是说 (
DB_ROLL_PTR
IS NULL ORDB_ROLL_PTR
> 当前的查询的事物版本号)这样确保查询出来的数据行记录在事务开启之前没有被删除。
-
最后我们该如何学习?
1、看视频进行系统学习
这几年的Crud经历,让我明白自己真的算是菜鸡中的战斗机,也正因为Crud,导致自己技术比较零散,也不够深入不够系统,所以重新进行学习是很有必要的。我差的是系统知识,差的结构框架和思路,所以通过视频来学习,效果更好,也更全面。关于视频学习,个人可以推荐去B站进行学习,B站上有很多学习视频,唯一的缺点就是免费的容易过时。
另外,我自己也珍藏了好几套视频资料躺在网盘里,有需要的我也可以分享给你:
2、读源码,看实战笔记,学习大神思路
“编程语言是程序员的表达的方式,而架构是程序员对世界的认知”。所以,程序员要想快速认知并学习架构,读源码是必不可少的。阅读源码,是解决问题 + 理解事物,更重要的:看到源码背后的想法;程序员说:读万行源码,行万种实践。
Spring源码深度解析:
Mybatis 3源码深度解析:
Redis学习笔记:
Spring Boot核心技术-笔记:
3、面试前夕,刷题冲刺
面试的前一周时间内,就可以开始刷题冲刺了。请记住,刷题的时候,技术的优先,算法的看些基本的,比如排序等即可,而智力题,除非是校招,否则一般不怎么会问。
关于面试刷题,我个人也准备了一套系统的面试题,帮助你举一反三:
只有技术过硬,在哪儿都不愁就业,“万般带不去,唯有业随身”学习本来就不是在课堂那几年说了算,而是在人生的旅途中不间断的事情。
人生短暂,别稀里糊涂的活一辈子,不要将就。
资料领取方式:点击蓝色传送门免费领取上述资料
文章内容中涉及到的Java面试题、源码文档,技术笔记等学习资料,均可以免费分享给大家学习,只需你动动手多多支持即可!
稀里糊涂的活一辈子,不要将就。
资料领取方式:点击蓝色传送门免费领取上述资料
文章内容中涉及到的Java面试题、源码文档,技术笔记等学习资料,均可以免费分享给大家学习,只需你动动手多多支持即可!