Java进阶:java容器类的作用

Posted Java范德萨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java进阶:java容器类的作用相关的知识,希望对你有一定的参考价值。

一、前言

有句话:正因为你优秀,所以难以卓越!

刚开始听这句话还在上学,既不卓越、也不优秀,甚至可能还有点笨!但突然从某次爬到班级的前几名后,开始喜欢上了这种感觉,原来前面的风景是如此灿烂😜!

优秀和卓越差的不是一个等级,当你感觉自己优秀后,还能保持空瓶的心态开始,才能逐步的像卓越迈进,并漫漫长!

是不小时候更容易学会更多的知识,但越大越笨了!人可能很容易被自己的年纪大了,当成长者。却很少能保持一个低姿态谦卑的心态,不断的学习。所以最后,放不下自己,也拾不起能力。

喜欢一句话,蓝是天的颜色、红是火的象征,我不学大海抄袭天的蓝、也不学晚霞模拟火的红。我就是我,生命是我的、命运是我的。健身也是你的、学习也是你的,只要你有一个好心态,自然会走到前面卓越那里!

正文

谈到 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

    1. 更新数据时,插入一条新的数据,DB_TRX_ID 记录的是当前更新数据的事物版本号

    2. 将旧数据的 DB_ROLL_PTR 值更新为当前更新数据的事物版本号

  • SELECT

    查询规则如下:

    1. 查找数据行版本号早于当前事务版本号的数据行记录,也就是说(当前的查询的事物版本号 >= DB_TRX_ID 中的值)

      这样就能确保事物读取的数据,要么是当前事物已经存在的,要么是当前事物所操作过的。

    2. 查找删除版本号要么为NULL,要么大于当前事务版本号的记录。也就是说 (DB_ROLL_PTR IS NULL OR DB_ROLL_PTR > 当前的查询的事物版本号)

      这样确保查询出来的数据行记录在事务开启之前没有被删除。

最后

需要的朋友戳这里即可免费获取这份大牛的学习笔记哦~

腾讯T3大牛总结的500页MySQL实战笔记意外爆火,P8看了直呼内行

需要的朋友戳这里即可免费获取这份大牛的学习笔记哦~

[外链图片转存中…(img-YQRsGc4g-1621411011668)]

腾讯T3大牛总结的500页MySQL实战笔记意外爆火,P8看了直呼内行

以上是关于Java进阶:java容器类的作用的主要内容,如果未能解决你的问题,请参考以下文章

Java进阶之光!2021必看-Java高级面试题总结

java 代码片段

Java进阶知识点2:看不懂的代码 - 协变与逆变

Scala编程进阶

Java进阶容器学习

java中的 validate()有啥作用