|
|
@ -1141,7 +1141,7 @@ InnoDB实现回滚靠的是undo log。当事务对数据库进行修改时,Inn
|
|
|
|
|
|
|
|
|
|
|
|
**一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。**
|
|
|
|
**一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。**
|
|
|
|
|
|
|
|
|
|
|
|
数据库的完整性约束包括但不限于:实体完整性(如行的主键存在且唯一)、列完整性(如字段的类型、大小、长度要符合要求)、外键约束、用户自定义完整性(如转账前后,两个账户余额的和应该不变)。
|
|
|
|
数据库的完整性约束包括但不限于:实体完整性(如行的主键存在且唯一)、列完整性(如字段的类型、大小、长度要符合要求)、外键约束、用户自定义完整性(如转账前后,两个账户余额的和应该不变)。假如A账户给B账户转10块钱,不管成功与否,A和B的总金额是不变的。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1167,7 +1167,7 @@ InnoDB实现回滚靠的是undo log。当事务对数据库进行修改时,Inn
|
|
|
|
|
|
|
|
|
|
|
|
隔离性追求的是并发情形下事务之间互不干扰。主要分为两个方面:
|
|
|
|
隔离性追求的是并发情形下事务之间互不干扰。主要分为两个方面:
|
|
|
|
|
|
|
|
|
|
|
|
**① 锁机制保证隔离性**:(一个事务)写操作对(另一个事务)写操作的影响
|
|
|
|
**① 加锁机制保证隔离性**:(一个事务)写操作对(另一个事务)写操作的影响
|
|
|
|
|
|
|
|
|
|
|
|
事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其它事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。
|
|
|
|
事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其它事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。
|
|
|
|
|
|
|
|
|
|
|
@ -1234,10 +1234,20 @@ MVCC全称Multi-Version Concurrency Control,即多版本的并发控制协议
|
|
|
|
|
|
|
|
|
|
|
|
在事务的并发操作中,不做隔离操作则可能会出现 **脏读、不可重复读、幻读** 问题:
|
|
|
|
在事务的并发操作中,不做隔离操作则可能会出现 **脏读、不可重复读、幻读** 问题:
|
|
|
|
|
|
|
|
|
|
|
|
- **脏读**:**事务A中读到了事务B中未提交的更新数据内容**。然后B回滚操作,那么A读取到的数据是脏数据
|
|
|
|
- **脏读**:**指一个事务读取到了另一个未提交事务修改过的数据**
|
|
|
|
- **不可重复读**:**事务A读到事务B已经提交后的数据**。即事务A多次读取同一数据时,返回结果不一致
|
|
|
|
|
|
|
|
- **幻读**:事物A执行select后,事物B**增或删**了一条数据,事务A再执行同一条SQL后发现多或少了一条数据
|
|
|
|
事务A中读到了事务B中未提交的更新数据内容,然后B回滚操作,那么A读取到的数据是脏数据。
|
|
|
|
- **第一类丢失更新:** A事务撤销事务时,覆盖了B事务提交的事务(现代关系型数据库中已经不会发生)
|
|
|
|
|
|
|
|
|
|
|
|
- **不可重复读**:**同一个事务内,前后多次读取,读取到的数据内容不一致**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
事务A读到事务B已经提交后的数据,即事务A多次读取同一数据时,返回结果不一致。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- **幻读**:**指一个事务先根据某些搜索条件查询出一些记录,在该事务未提交时,另一个事务写入了一些符合那些搜索条件的记录(如insert、delete、update),再次查询出的结果则出现不一致**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
事物A执行select后,事物B增或删了一条数据,事务A再执行同一条SQL后发现多或少了一条数据。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- **第一类丢失更新:** A事务撤销事务时,覆盖了B事务提交的事务(现代关系型数据库中已经不会发生)
|
|
|
|
|
|
|
|
|
|
|
|
- **第二类丢失更新:** A事务提交事务时,覆盖了B事务提交的事务(是不可重复读的特殊情况)
|
|
|
|
- **第二类丢失更新:** A事务提交事务时,覆盖了B事务提交的事务(是不可重复读的特殊情况)
|
|
|
|
|
|
|
|
|
|
|
|
**小结**:不可重复读的和幻读很容易混淆,**不可重复读**侧重于**修改**,**幻读**侧重于**新增或删除**。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。查看 `mysql` 事务隔离级别:`show variables like 'tx_iso%';`。
|
|
|
|
**小结**:不可重复读的和幻读很容易混淆,**不可重复读**侧重于**修改**,**幻读**侧重于**新增或删除**。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。查看 `mysql` 事务隔离级别:`show variables like 'tx_iso%';`。
|
|
|
@ -1257,11 +1267,11 @@ MVCC全称Multi-Version Concurrency Control,即多版本的并发控制协议
|
|
|
|
|
|
|
|
|
|
|
|
### Read Uncommitted(读未提交)
|
|
|
|
### Read Uncommitted(读未提交)
|
|
|
|
|
|
|
|
|
|
|
|
**即读取到了其它事务未提交的内容(可能会被回滚)**。在该隔离级别,**所有事务都可以看到其他未提交事务的执行结果**。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为**脏读(Dirty Read)**。
|
|
|
|
只限制了两个数据**不能同时修改**,但即使事务未提交也会**读取到其它事务未提交的内容(可能会被回滚)**。会有**脏读、重复读、幻读**的问题,读取未提交的数据,也被称之为**脏读(Dirty Read)**。
|
|
|
|
|
|
|
|
|
|
|
|
**特点**:最低级别,任何情况都无法保证
|
|
|
|
**特点**:最低级别,任何情况都无法保证
|
|
|
|
|
|
|
|
|
|
|
|
**读未提交的数据库锁情况**
|
|
|
|
**数据库锁情况**
|
|
|
|
|
|
|
|
|
|
|
|
- 读取数据:**未加锁,每次都读到最新数据,性能最好**
|
|
|
|
- 读取数据:**未加锁,每次都读到最新数据,性能最好**
|
|
|
|
- 写入数据:**只对数据增加行级共享锁,写完释放**
|
|
|
|
- 写入数据:**只对数据增加行级共享锁,写完释放**
|
|
|
@ -1270,13 +1280,13 @@ MVCC全称Multi-Version Concurrency Control,即多版本的并发控制协议
|
|
|
|
|
|
|
|
|
|
|
|
### Read Committed(读已提交)
|
|
|
|
### Read Committed(读已提交)
|
|
|
|
|
|
|
|
|
|
|
|
**即读取到了其它事务已提交的内容**。一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持所谓的**不可重复读(Nonrepeatable Read)**,因为同一事务的其他实例在该实例处理期间可能会有新的commit,所以同一select可能返回不同结果。
|
|
|
|
当前事务只能读取到其它事务**已提交**的数据。因同一事务的其它实例在该实例处理期间可能会有新的commit,所以同一select可能返回不同结果,这就是所谓的**不可重复读(Nonrepeatable Read)**。该隔离级别**解决了脏读**问题,但还是会存在**重复读、幻读**问题。
|
|
|
|
|
|
|
|
|
|
|
|
**特点**:避免脏读
|
|
|
|
**特点**:避免脏读
|
|
|
|
|
|
|
|
|
|
|
|
**脏读解决方案:基于乐观锁理论的MVCC(多版本并发控)实现**
|
|
|
|
**脏读解决方案**:基于乐观锁理论的MVCC(多版本并发控)实现
|
|
|
|
|
|
|
|
|
|
|
|
**读已提交的数据库锁情况**
|
|
|
|
**数据库锁情况**
|
|
|
|
|
|
|
|
|
|
|
|
- 读取数据:**加行级共享锁(读到时才加锁),读完后立即释放**
|
|
|
|
- 读取数据:**加行级共享锁(读到时才加锁),读完后立即释放**
|
|
|
|
- 写入数据:**在更新时的瞬间对其加行级排它锁,直到事务结束才释放**
|
|
|
|
- 写入数据:**在更新时的瞬间对其加行级排它锁,直到事务结束才释放**
|
|
|
@ -1285,15 +1295,15 @@ MVCC全称Multi-Version Concurrency Control,即多版本的并发控制协议
|
|
|
|
|
|
|
|
|
|
|
|
### Repeatable Read(可重复读)
|
|
|
|
### Repeatable Read(可重复读)
|
|
|
|
|
|
|
|
|
|
|
|
**它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行**。但会导致**幻读 (Phantom Read)**问题。
|
|
|
|
限制了读取数据时**不可以进行修改**,所以**解决了不能重复读**的问题。但是读取范围数据的时候,是可以插入或删除数据,所以还会存在**幻读(Phantom Read)**问题。
|
|
|
|
|
|
|
|
|
|
|
|
**幻读** 是户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当该用户再读取该范围的数据行时,会发现有新的“幻影” 行。
|
|
|
|
**幻读** 是户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当该用户再读取该范围的数据行时,会发现有新的“幻影” 行。
|
|
|
|
|
|
|
|
|
|
|
|
**特点**:避免脏读、不可重复读。MySQL默认事务隔离级别
|
|
|
|
**特点**:避免脏读、不可重复读。MySQL默认事务隔离级别
|
|
|
|
|
|
|
|
|
|
|
|
**不可重复读解决方案:基于乐观锁理论的MVCC(多版本并发控)实现**
|
|
|
|
**不可重复读解决方案**:基于乐观锁理论的MVCC(多版本并发控)实现
|
|
|
|
|
|
|
|
|
|
|
|
**可重复读的数据库锁情况**
|
|
|
|
**数据库锁情况**
|
|
|
|
|
|
|
|
|
|
|
|
- 读取数据:**开始读取的瞬间对其增加行级共享锁,直到事务结束才释放**
|
|
|
|
- 读取数据:**开始读取的瞬间对其增加行级共享锁,直到事务结束才释放**
|
|
|
|
- 写入数据:**开始更新的瞬间对其增加行级排他锁,直到事务结束才释放**
|
|
|
|
- 写入数据:**开始更新的瞬间对其增加行级排他锁,直到事务结束才释放**
|
|
|
@ -1302,11 +1312,11 @@ MVCC全称Multi-Version Concurrency Control,即多版本的并发控制协议
|
|
|
|
|
|
|
|
|
|
|
|
### Serializable(可串行化)
|
|
|
|
### Serializable(可串行化)
|
|
|
|
|
|
|
|
|
|
|
|
**指一个事务在执行过程中完全看不到其他事务对数据库所做的更新**。当两个事务同时操作数据库中相同数据时,如果第一个事务已经在访问该数据,第二个事务只能停下来等待,必须等到第一个事务结束后才能恢复运行。因此这两个事务实际上是串行化方式运行。
|
|
|
|
所有事务都是进行**串行化顺序**执行的。可以避免**脏读**、**不可重复读**与**幻读**所有并发问题。但该事务隔离级别下,事务执行很耗性能。
|
|
|
|
|
|
|
|
|
|
|
|
**特点**:避免脏读、不可重复读、幻读
|
|
|
|
**特点**:避免脏读、不可重复读、幻读
|
|
|
|
|
|
|
|
|
|
|
|
**可序列化的数据库锁情况**
|
|
|
|
**数据库锁情况**
|
|
|
|
|
|
|
|
|
|
|
|
- 读取数据:**先对其加表级共享锁 ,直到事务结束才释放**
|
|
|
|
- 读取数据:**先对其加表级共享锁 ,直到事务结束才释放**
|
|
|
|
- 写入数据:**先对其加表级排他锁 ,直到事务结束才释放**
|
|
|
|
- 写入数据:**先对其加表级排他锁 ,直到事务结束才释放**
|
|
|
|