Skip to content

Commit 3bdd116

Browse files
committed
Update Java Notes
1 parent 411b33b commit 3bdd116

File tree

3 files changed

+508
-242
lines changed

3 files changed

+508
-242
lines changed

DB.md

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5702,19 +5702,18 @@ MySQL Server 是多线程结构,包括后台线程和客户服务线程。多
57025702

57035703
### 隔离级别
57045704

5705+
#### 四种级别
5706+
57055707
事务的隔离级别:多个客户端操作时,各个客户端的事务之间应该是隔离的,**不同的事务之间不该互相影响**,而如果多个事务操作同一批数据时,则需要设置不同的隔离级别,否则就会产生问题。
57065708

57075709
隔离级别分类:
57085710

57095711
| 隔离级别 | 名称 | 会引发的问题 | 数据库默认隔离级别 |
57105712
| ---------------- | -------- | ---------------------- | ------------------- |
5711-
| read uncommitted | 读未提交 | 脏读、不可重复读、幻读 | |
5712-
| read committed | 读已提交 | 不可重复读、幻读 | Oracle / SQL Server |
5713-
| repeatable read | 可重复读 | 幻读 | MySQL |
5714-
| serializable | 可串行化 || |
5715-
5716-
* 串行化:让所有事务按顺序单独执行,写操作会加写锁,读操作会加读锁
5717-
* 可串行化:让所有操作相同数据的事务顺序执行,通过加锁实现
5713+
| Read Uncommitted | 读未提交 | 脏读、不可重复读、幻读 | |
5714+
| Read Committed | 读已提交 | 不可重复读、幻读 | Oracle / SQL Server |
5715+
| Repeatable Read | 可重复读 | 幻读 | MySQL |
5716+
| Serializable | 可串行化 || |
57185717

57195718
一般来说,隔离级别越低,系统开销越低,可支持的并发越高,但隔离性也越差
57205719

@@ -5745,6 +5744,31 @@ MySQL Server 是多线程结构,包括后台线程和客户服务线程。多
57455744

57465745

57475746

5747+
***
5748+
5749+
5750+
5751+
#### 加锁分析
5752+
5753+
InnoDB 存储引擎支持事务,所以加锁分析是基于该存储引擎
5754+
5755+
* Read Uncommitted 级别,任何操作都不会加锁
5756+
5757+
* Read Committed 级别,增删改操作会加写锁(行锁),读操作不加锁
5758+
5759+
MySQL 做了优化,在 Server 层过滤条件时发现不满足的记录会调用 unlock_row 方法释放该记录的行锁,保证最后只有满足条件的记录加锁,但是扫表过程中每条记录的**加锁操作不能省略**。所以对数据量很大的表做批量修改时,如果无法使用相应的索引,需要在Server 过滤数据时就会特别慢,出现虽然没有修改某些行的数据,但是还是被锁住了的现象,这种情况同样适用于 RR
5760+
5761+
* Repeatable Read 级别,增删改操作会加写锁,读操作不加锁。因为读写锁不兼容,加了写锁后其他事务就无法修改数据,影响了并发性能,为了保证隔离性和并发性,MySQL 通过 MVCC 解决了读写冲突。RR 级别下的锁有很多种,锁机制章节详解
5762+
5763+
* Serializable 级别,读加共享锁,写加排他锁,读写互斥,使用的悲观锁的理论,实现简单,数据更加安全,但是并发能力非常差
5764+
5765+
* 串行化:让所有事务按顺序单独执行,写操作会加写锁,读操作会加读锁
5766+
* 可串行化:让所有操作相同数据的事务顺序执行,通过加锁实现
5767+
5768+
5769+
5770+
参考文章:https://tech.meituan.com/2014/08/20/innodb-lock.html
5771+
57485772

57495773

57505774
***
@@ -6636,7 +6660,7 @@ InnoDB 与 MyISAM 的最大不同有两点:一是支持事务;二是采用
66366660
- 共享锁 (S):又称为读锁,简称 S 锁,多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改
66376661
- 排他锁 (X):又称为写锁,简称 X 锁,不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,只有获取排他锁的事务是可以对数据读取和修改
66386662

6639-
对于 UPDATE、DELETE 和 INSERT 语句,InnoDB 会**自动给涉及数据集加排他锁**(行锁),在 commit 的时候会自动释放(在事务中加的锁,会**在事务中止或提交时自动释放**);对于普通 SELECT 语句,不会加任何锁
6663+
RR 隔离界别下,对于 UPDATE、DELETE 和 INSERT 语句,InnoDB 会**自动给涉及数据集加排他锁**(行锁),在 commit 的时候会自动释放(在事务中加的锁,会**在事务中止或提交时自动释放**);对于普通 SELECT 语句,不会加任何锁(只是针对 InnoDB 层来说的,因为在 Server 层会加 MDL 读锁),通过 MVCC 防止冲突
66406664

66416665
锁的兼容性:
66426666

@@ -6654,7 +6678,7 @@ SELECT * FROM table_name WHERE ... FOR UPDATE -- 排他锁
66546678

66556679

66566680

6657-
****
6681+
***
66586682

66596683

66606684

@@ -6999,6 +7023,8 @@ lock_id 是锁 id;lock_trx_id 为事务 id;lock_mode 为 X 代表排它锁
69997023

70007024
### 乐观锁
70017025

7026+
悲观锁:在整个数据处理过程中,将数据处于锁定状态,为了保证事务的隔离性,就需要一致性锁定读。读取数据时给加锁,其它事务无法修改这些数据,修改删除数据时也加锁,其它事务同样无法读取这些数据
7027+
70027028
悲观锁和乐观锁使用前提:
70037029

70047030
- 对于读的操作远多于写的操作的时候,一个更新操作加锁会阻塞所有的读取操作,降低了吞吐量,最后需要释放锁,锁是需要一些开销的,这时候可以选择乐观锁

0 commit comments

Comments
 (0)