auto commit

This commit is contained in:
CyC2018 2018-03-22 15:50:12 +08:00
parent 60e5002cde
commit 34c15646cc

View File

@ -14,7 +14,10 @@
* [版本号](#版本号) * [版本号](#版本号)
* [Undo 日志](#undo-日志) * [Undo 日志](#undo-日志)
* [实现过程](#实现过程) * [实现过程](#实现过程)
* [六、间隙锁](#六间隙锁) * [六、Next-Key Locks](#六next-key-locks)
* [Record Locks](#record-locks)
* [Grap Locks](#grap-locks)
* [Next-Key Locks](#next-key-locks)
* [七、关系数据库设计理论](#七关系数据库设计理论) * [七、关系数据库设计理论](#七关系数据库设计理论)
* [函数依赖](#函数依赖) * [函数依赖](#函数依赖)
* [异常](#异常) * [异常](#异常)
@ -211,21 +214,21 @@ 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 在读取和修改数据行时无需加锁,这属于乐观锁的一种实现。正因为无需加锁,因此性能上也会更好。 InnoDB 的 MVCC 在读取和修改数据行时无需加锁,这属于乐观锁的一种实现。正因为无需加锁,因此性能上也会更好。
InnoDB 的 MVCC 可以用于实现提交读和可重复读。未提交读总是读取最新的数据行,无需使用 MVCC可串行化需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。 InnoDB 的 MVCC 可以用于实现提交读和可重复读这两种隔离级别而对于未提交读隔离级别,它总是读取最新的数据行,无需使用 MVCC可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。
## 版本号 ## 版本号
- 系统版本号:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。 - 系统版本号:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。
- 事务版本号:事务开始时的系统版本号。 - 事务版本号:事务开始时的系统版本号。
InooDB 的 MVCC 在每行记录后面都保存着两个隐藏的列,用来存储个版本号: InooDB 的 MVCC 在每行记录后面都保存着两个隐藏的列,用来存储个版本号:
- 创建版本号:指示创建一个数据行的快照时的系统版本号; - 创建版本号:指示创建一个数据行的快照时的系统版本号;
- 删除版本号:如果该快照的删除版本号大于当前事务版本号表示该快照有效,否则该快照无法读取 - 删除版本号:如果该快照的删除版本号大于当前事务版本号表示该快照有效,否则表示该快照已经被删除了
## Undo 日志 ## Undo 日志
@ -241,9 +244,9 @@ InnoDB 的 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回
当开始新一个事务时,该事务的版本号肯定会大于所有数据行快照的创建版本号,理解这一点很关键。 当开始新一个事务时,该事务的版本号肯定会大于所有数据行快照的创建版本号,理解这一点很关键。
把没对一个数据行做修改的事务称为 T<sub>1</sub>T<sub>1</sub> 所要读取的数据行快照的创建版本号必须小于当前事务的版本号,因为如果大于或者等于当前事务的版本号,那么该数据行快照是其它事务的最新修改,因此不能去读取它。 把没对一个数据行做修改的事务称为 T<sub>1</sub>T<sub>1</sub> 所要读取的数据行快照的创建版本号必须小于当前事务的版本号,因为如果大于或者等于当前事务的版本号,那么表示该数据行快照是其它事务的最新修改,因此不能去读取它。
除了上面的要求T<sub>1</sub> 所要读取的数据行快照的删除版本号必须小于当前事务版本号,因为如果大于或者等于当前事务版本号,那么该数据行快照是已经被删除的,不应该去读取它。 除了上面的要求T<sub>1</sub> 所要读取的数据行快照的删除版本号必须小于当前事务版本号,因为如果大于或者等于当前事务版本号,那么表示该数据行快照是已经被删除的,不应该去读取它。
### 2. INSERT ### 2. INSERT
@ -257,7 +260,49 @@ InnoDB 的 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回
将系统版本号作为更新后的数据行快照的创建版本号,同时将系统版本号作为作为更新前的数据行快照的删除版本号。可以理解为新执行 DELETE 后执行 INSERT。 将系统版本号作为更新后的数据行快照的创建版本号,同时将系统版本号作为作为更新前的数据行快照的删除版本号。可以理解为新执行 DELETE 后执行 INSERT。
# 六、间隙锁 # 六、Next-Key Locks
以下内容都是针对 MySQL 的 InnoDB 存储引擎来讨论的。
和 MVCC 一样Next-Key Locks 也是一种实现隔离级别的一种方式。相比于 MVCC它可以解决幻读问题。
## Record Locks
锁定的对象时索引而不是数据。如果表没有设置索引InnoDB 会自动在主键上创建隐藏的聚集索引,因此 Record Lock 依然可以使用。
## Grap Locks
锁定一个范围内的索引,例如当一个事务执行以下语句,其它事务就不能在 t.c1 中插入 15。
```sql
SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;
```
## Next-Key Locks
它是 Record Locks 和 Gap Locks 的结合。在 user 中有以下记录:
```sql
| id | last_name | first_name | age |
|------|-------------|--------------|-------|
| 4 | stark | tony | 21 |
| 1 | tom | hiddleston | 30 |
| 3 | morgan | freeman | 40 |
| 5 | jeff | dean | 50 |
| 2 | donald | trump | 80 |
+------|-------------|--------------|-------+
```
那么就需要锁定以下范围:
```sql
(-∞, 21]
(21, 30]
(30, 40]
(40, 50]
(50, 80]
(80, ∞)
```
# 七、关系数据库设计理论 # 七、关系数据库设计理论
@ -499,3 +544,5 @@ Entity-Relationship有三个组成部分实体、属性、联系。
- [三级模式与两级映像](http://blog.csdn.net/d2457638978/article/details/48783923) - [三级模式与两级映像](http://blog.csdn.net/d2457638978/article/details/48783923)
- [Database Normalization and Normal Forms with an Example](https://aksakalli.github.io/2012/03/12/database-normalization-and-normal-forms-with-an-example.html) - [Database Normalization and Normal Forms with an Example](https://aksakalli.github.io/2012/03/12/database-normalization-and-normal-forms-with-an-example.html)
- [The basics of the InnoDB undo logging and history system](https://blog.jcole.us/2014/04/16/the-basics-of-the-innodb-undo-logging-and-history-system/) - [The basics of the InnoDB undo logging and history system](https://blog.jcole.us/2014/04/16/the-basics-of-the-innodb-undo-logging-and-history-system/)
- [MySQL locking for the busy web developer](https://www.brightbox.com/blog/2013/10/31/on-mysql-locks/)
- [浅入浅出 MySQL 和 InnoDB](https://draveness.me/mysql-innodb)