数据库
事务
事务(Transaction)指一个操作,由多个步骤组成,要么全部成功,要么全部失败。
举例:转账,假设A账户向B账号转账,那么涉及两个操作:
从 A 账户扣钱。
往 B 账户加入等量的钱。
在这种场景下,不能A 账户扣了钱,B 账户却没加钱的情况,要么同时成功,要么同时失败并回滚。
事务四大特性
A 原子性(Atomicity):作为一个整体,包含在其中的对数据库的操作要么全部被执行,要么都不执行
C 一致性(Consistency):事务在执行前后,数据库必须满足一些预定义的一致性规则,否则回滚
I 隔离性(Isolation):多个事务并发执行时,一个事务的执行不影响其他事务的执行
D 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中
事务并发问题
-
脏读(Dirty Read):读取未提交数据。
事务 A 读取事务 B 尚未提交的数据,此时如果事务 B 发生错误并回滚,那么事务 A 读取到的数据就是脏数据。
-
不可重复读(Non-repeatable Read):前后多次读取,数据内容不一致。
事务 A 在事务 B 开始前读和事务 B 结束后读的数据不一样,因为数据被事务 B 修改了。
-
幻读(Phantom Read):同一个查询在不同时间产生不同的结果集
事务 A 在读取某个范围内的记录时,事务 B 在该范围内插入了新记录或删除了旧记录,事务 A 再次读取该范围内的记录时,前后获取的结果集不同,产生了幻读。
事务隔离级别
- 读未提交(Read Uncommitted)
- 读已提交(Read Committed)
- 可重复读(Repeatable Read)
- 串行化(Serializable)
MVCC
多版本并发控制,以乐观锁为理论基础。
通过对数据行的多个版本管理来实现数据库的并发控制。这样就可以通过比较版本号决定数据是否显示,读取数据时不需要加锁也可保证事务的隔离效果。
MVCC 的核心实现主要基于两部分:版本链和读视图。
MVCC 通过版本链实现多版本管理,通过 Read View 生成策略的不同实现,实现「读已提交」和「可重复读」这两种隔离级别。
- 「读已提交」每次查询都会重新生成一个 Read View,做到每次提交后的数据可被当前事务读到。
- 「可重复读」一直使用启动事务时生成的 Read View,直到当前事务提交,以此保证可重复读。