auto commit

This commit is contained in:
CyC2018 2018-03-22 14:03:53 +08:00
parent 8553467648
commit c49facf7bc

View File

@ -11,6 +11,9 @@
* [封锁协议](#封锁协议)
* [四、隔离级别](#四隔离级别)
* [五、多版本并发控制](#五多版本并发控制)
* [版本号](#版本号)
* [Undo 日志](#undo-日志)
* [实现过程](#实现过程)
* [六、关系数据库设计理论](#六关系数据库设计理论)
* [函数依赖](#函数依赖)
* [异常](#异常)
@ -181,26 +184,52 @@ lock-x(A)...unlock(A)...lock-s(B)...unlock(B)...lock-s(c)...unlock(C)...
# 五、多版本并发控制
未完待续)
Multi-Version Concurrency Control, MVCC是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,它的基本思想是通过保存每个数据行的多个版本,在并发操作控制多个事务访问某个版本,从而保证多个事务对同一个数据行读取的结果是一致的。
Multi-Version Concurrency Control, MVCC是 MySQL 的 InnoDB 存储引擎实现的一种并发控制方式,通过保存数据在某个时间点的快照,让多个事务对同一个数据的读取结果是一致的
InnoDB 的 MVCC 在读取和修改数据行时无需加锁,这属于乐观锁的一种实现。正因为无需加锁,因此性能上也会更好
MVCC 可以工作在提交读和可重复读两个隔离级别下,因为未提交读总是读取最新的数据行,可串行化会对所有读取的行都加锁
InnoDB 的 MVCC 可以用于实现提交读和可重复读。未提交读总是读取最新的数据行,无需使用 MVCC而可串行化需要对所有读取的行都加锁单纯使用 MVCC 无法实现
<font size=4> **版本号是一个** </font></br>
## 版本号
版本是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。
- 系统版本号:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。
- 事务版本号:事务开始时的系统版本号。
事务的版本号为事务开始时的系统版本号。
InooDB 的 MVCC 在每行记录后面都保存着两个隐藏的列,用来存储来个版本号:
InooDB 的 MVCC 在每行记录后面都保存着两个隐藏的列,一个列保存着创建的版本号,一个列保存着删除的版本号。
- 创建版本号:指示创建一个数据行的快照时的系统版本号;
- 删除版本号:如果该快照的删除版本号大于当前事务版本号表示该快照有效,否则该快照无法读取。
<font size=4> **Undo 日志** </font></br>
## Undo 日志
MVCC 实现使用到的快照其实是 Undo 日志它通过回滚指针把一个数据行Record的所有版本连接起来。
InnoDB 的 MVCC 使用到的快照存储在 Undo 日志中该日志通过回滚指针把一个数据行Record的所有快照连接起来。
<div align="center"> <img src="../pics//e41405a8-7c05-4f70-8092-e961e28d3112.jpg"/> </div><br>
## 实现过程
### 1. SELECT
该操作必须保证多个事务读取到同一个数据行的快照。但是也有例外,如果有一个事务正在修改该数据行,那么它可以读取事务本身所做的修改,而不用和其它事务的读取结果一致。
当开始新一个事务时,该事务的版本号肯定会大于所有数据行快照的创建版本号,理解这一点很关键。
把没对一个数据行做修改的事务称为 T<sub>1</sub>T<sub>1</sub> 所要读取的数据行快照的创建版本号必须小于当前事务的版本号,因为如果大于或者等于当前事务的版本号,那么该数据行快照是其它事务的最新修改,因此不能去读取它。
除了上面的要求T<sub>1</sub> 所要读取的数据行快照的删除版本号必须小于当前事务版本号,因为如果大于或者等于当前事务版本号,那么该数据行快照是已经被删除的,不应该去读取它。
### 2. INSERT
将系统版本号作为数据行快照的创建版本号。
### 3. DELETE
将系统版本号作为数据行快照的删除版本号。
### 4. UPDATE
将系统版本号作为更新后的数据行快照的创建版本号,同时将系统版本号作为作为更新前的数据行快照的删除版本号。可以理解为新执行 DELETE 后执行 INSERT。
# 六、关系数据库设计理论
## 函数依赖