Skip to content

Commit 794063c

Browse files
committed
知识点总结:完善数据库事务
1 parent ad0faf7 commit 794063c

File tree

3 files changed

+67
-14
lines changed

3 files changed

+67
-14
lines changed

points/2.Mysql/SQL优化.md

Whitespace-only changes.

points/2.Mysql/数据库事务.md

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,63 @@
33

44
# ACID是什么
55

6-
Atomicity:原子性 要么成功要么失败
6+
## Atomicity:原子性
77

8-
Consistency:一致性,在事务结束后和结束前是一致的,比如update name='xdq',在事务commit后,name就是'xdq'
8+
要么成功要么失败,如果有两步操作,第二步失败需要第一步回滚才能保证两步的原子性。
99

10-
Isolation:隔离性 事务之间的数据互相不干扰的,就是我在A事务里更新的数据,在B事务是无感知的,
10+
### 实现原理
1111

12-
Durability:持久性 事务结束后数据的改变是永久的,也就是实打实的存在数据库中了
12+
基于undo log实现原子性。
13+
14+
每次操作都会记录本次操作的信息,差不多是哪一条数据,哪些数据,什么操作,修改前和修改后的数据。 当操作失败后,会根据undo log中的信息,恢复到之前的信息。
15+
16+
## Durability:持久性
17+
18+
事务结束后数据的改变是永久的,也就是实打实的存在数据库中了
19+
20+
### 实现原理
21+
22+
基于redo log实现的。
23+
24+
数据库数据是存放在磁盘中的,每次从磁盘中读取数据其实是很慢的操作。所以mysql使用缓冲存放没一页的数据,获取/修改数据首先从缓冲中获取,获取不到再从磁盘获取并存在缓冲中。
25+
26+
因为缓冲是临时内存,数据库宕机会丢失缓冲中的数据,所以为了解决这个问题使用redo log.
27+
28+
每次更新数据都会先存储到redo log中再到缓冲中,事务提交会将redo log中的数据刷新到磁盘中,当服务器宕机重启后会从redo log中恢复丢失的数据。
29+
30+
### redo log 与binlog的区别
31+
32+
目的不同:redo log更多是为了事务和服务器宕机自动恢复保存数据持久性的,binlog是数据库log,可以用于恢复某个时间点的数据,和reply log做主从同步的。
33+
34+
存储数据时机不同:redo log是每次修改就存储,而binlog是事务commit后存储的。
35+
36+
实现不同:redo log是InnoDB引擎的机制,binlog是mysql服务的机制。
37+
38+
存储格式不同:binlog是二进制。
39+
40+
## Isolation:隔离性
41+
42+
事务之间的数据互相不干扰的,就是我在A事务里更新的数据,在B事务是无感知的。
43+
44+
### 实现原理
45+
46+
基于锁机制和版本控制(MVCC)实现
47+
48+
Mysql默认使用RR(repeatable read)
49+
50+
使用间隙锁保证幻读,确定返回内的值每次都一样。比如age>100.
51+
52+
#### MVCC
53+
54+
使用undo log实现,记录每次的信息,根据版本去实现隔离。
55+
56+
## Consistency:一致性
57+
58+
在事务结束后和结束前是一致的,比如update name='xdq',在事务commit后,name就是'xdq'。
59+
60+
### 实现原理
61+
62+
基于原子性,持久性和隔离性来保证一致性的。
1363

1464
# 并发下事务带来的问题
1565

@@ -59,6 +109,7 @@ Durability:持久性 事务结束后数据的改变是永久的,也就是实
59109
使用读写隔离,使用不同隔离级别
60110

61111
## 配合使用锁机制
112+
62113
**排他锁** **写锁** 事务获取锁,此事务可以查询和修改,其他事务只能等待,不能读取和修改
63114
**共享锁** **读锁** 事务获取锁,此事务可以查询数据,其他事务也可以加锁,但只能查询数据但不能改数据。
64115

@@ -67,33 +118,35 @@ Durability:持久性 事务结束后数据的改变是永久的,也就是实
67118
## 隔离级别
68119

69120
### 一级 read uncommitted
70-
在没commit时,事务A里修改的数据,在其他事务里可以被查到变更的值。
71-
事务A获取共享锁修改数据,其他事务只能读不能修改。
121+
122+
在没commit时,事务A里修改的数据,在其他事务里可以被查到变更的值。 事务A获取共享锁修改数据,其他事务只能读不能修改。
72123

73124
因为可以在任何时刻都可以读取数据,所以**覆盖****脏读****不可重复读****幻读**都不能避免
74125

75126
### 二级 read committed
76-
事务A修改的数据在committed后可以被其他事务查询到变更的值。
77-
事务A在修改数据没提交前使用排他锁防止其他事务在这个期间获取到修改的值。
127+
128+
事务A修改的数据在committed后可以被其他事务查询到变更的值。 事务A在修改数据没提交前使用排他锁防止其他事务在这个期间获取到修改的值。
78129

79130
这种可以避免发生脏读,其他的避免不了
80131

81132
### 三级 可重复读
133+
82134
一个事务里读取到值每次都是一样的。
83135

84-
事务A在读取的时候就使用排他锁,其他事务可以读取数据但不能修改,修改就得等待事务A释放排他锁。
85-
事务A在commit后释放排他锁。
136+
事务A在读取的时候就使用排他锁,其他事务可以读取数据但不能修改,修改就得等待事务A释放排他锁。 事务A在commit后释放排他锁。
86137

87138
这样可以保证脏读和可重复读,但不能保证幻读。
88139

89-
其实还有个问题,在事务A修改后并且commit后,事务B此事查询为什么不能获取最新值,就是用排他锁锁和写锁,也不行啊。
90-
事务A都提交结束了,相当于锁都释放了,不会对事务B有什么限制。
140+
其实还有个问题,在事务A修改后并且commit后,事务B此事查询为什么不能获取最新值,就是用排他锁锁和写锁,也不行啊。 事务A都提交结束了,相当于锁都释放了,不会对事务B有什么限制。
91141

92142
大概了解了下是在每个事务都有自己的查询视图,事务B查询的是自己的视图,所以每次都一样。
93143

94-
mysql默认使用可重复读级别,使用MVCC解决幻读问题。
144+
mysql默认使用可重复读级别,使用MVCC解决重复读问题。 使用record lock(记录锁) + gap lock(间隙锁) 保证幻读
95145

96146
### 四级 串行化
147+
97148
就是阻塞式的等待当前事务提交完成才能进行下一个事务。
98149

99-
# MVCC
150+
# Mysql innoDB 使用PR如何隔离事务
151+
152+
如果不使用其他策略,PR其实不能避免不可重复读和幻读的,他是MVCC来实现的。

points/2.Mysql/数据库优化.md

Whitespace-only changes.

0 commit comments

Comments
 (0)