auto commit
This commit is contained in:
parent
cf21279738
commit
287f365615
|
@ -2,6 +2,7 @@
|
||||||
* [一、事务](#一事务)
|
* [一、事务](#一事务)
|
||||||
* [概念](#概念)
|
* [概念](#概念)
|
||||||
* [四大特性](#四大特性)
|
* [四大特性](#四大特性)
|
||||||
|
* [AUTOCOMMIT](#autocommit)
|
||||||
* [二、并发一致性问题](#二并发一致性问题)
|
* [二、并发一致性问题](#二并发一致性问题)
|
||||||
* [问题](#问题)
|
* [问题](#问题)
|
||||||
* [解决方法](#解决方法)
|
* [解决方法](#解决方法)
|
||||||
|
@ -9,6 +10,7 @@
|
||||||
* [封锁粒度](#封锁粒度)
|
* [封锁粒度](#封锁粒度)
|
||||||
* [封锁类型](#封锁类型)
|
* [封锁类型](#封锁类型)
|
||||||
* [封锁协议](#封锁协议)
|
* [封锁协议](#封锁协议)
|
||||||
|
* [MySQL 隐式与显示锁定](#mysql-隐式与显示锁定)
|
||||||
* [四、隔离级别](#四隔离级别)
|
* [四、隔离级别](#四隔离级别)
|
||||||
* [五、多版本并发控制](#五多版本并发控制)
|
* [五、多版本并发控制](#五多版本并发控制)
|
||||||
* [版本号](#版本号)
|
* [版本号](#版本号)
|
||||||
|
@ -48,15 +50,13 @@
|
||||||
|
|
||||||
## 四大特性
|
## 四大特性
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//09e6e8d4-4d83-4949-b908-6d6b4c2fd064.png"/> </div><br>
|
|
||||||
|
|
||||||
### 1. 原子性(Atomicity)
|
### 1. 原子性(Atomicity)
|
||||||
|
|
||||||
事务被视为不可分割的最小单元,要么全部提交成功,要么全部失败回滚。
|
事务被视为不可分割的最小单元,事务的所有操作要么全部提交成功,要么全部失败回滚。
|
||||||
|
|
||||||
### 2. 一致性(Consistency)
|
### 2. 一致性(Consistency)
|
||||||
|
|
||||||
事务执行前后都保持一致性状态。在一致性状态下,所有事务对一个数据的读取结果都是相同的。
|
数据库在事务执行前后都保持一致性状态。在一致性状态下,所有事务对一个数据的读取结果都是相同的。
|
||||||
|
|
||||||
### 3. 隔离性(Isolation)
|
### 3. 隔离性(Isolation)
|
||||||
|
|
||||||
|
@ -66,6 +66,10 @@
|
||||||
|
|
||||||
一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。可以通过数据库备份和恢复来保证持久性。
|
一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。可以通过数据库备份和恢复来保证持久性。
|
||||||
|
|
||||||
|
## AUTOCOMMIT
|
||||||
|
|
||||||
|
MySQL 默认采用自动提交模式。也就是说,如果不显示使用`START TRANSACTION`语句来开始一个事务,那么每个查询都会被当做一个事务自动提交。
|
||||||
|
|
||||||
# 二、并发一致性问题
|
# 二、并发一致性问题
|
||||||
|
|
||||||
在并发环境下,一个事务如果受到另一个事务的影响,那么事务操作就无法满足一致性条件。
|
在并发环境下,一个事务如果受到另一个事务的影响,那么事务操作就无法满足一致性条件。
|
||||||
|
@ -120,7 +124,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
|
||||||
|
|
||||||
## 封锁类型
|
## 封锁类型
|
||||||
|
|
||||||
### 1. 排它锁与共享锁
|
### 1. 读写锁
|
||||||
|
|
||||||
- 排它锁(Exclusive),简写为 X 锁,又称写锁。
|
- 排它锁(Exclusive),简写为 X 锁,又称写锁。
|
||||||
- 共享锁(Shared),简写为 S 锁,又称读锁。
|
- 共享锁(Shared),简写为 S 锁,又称读锁。
|
||||||
|
@ -134,26 +138,35 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
|
||||||
|
|
||||||
| - | X | S |
|
| - | X | S |
|
||||||
| :--: | :--: | :--: |
|
| :--: | :--: | :--: |
|
||||||
|X|No|No|
|
|X|NO|NO|
|
||||||
|S|No|Yes|
|
|S|NO|YES|
|
||||||
|
|
||||||
### 2. 意向锁
|
### 2. 意向锁
|
||||||
|
|
||||||
意向锁(Intention Locks)可以支持多粒度封锁。它本身是一个表锁,通过在原来的 X/S 锁之上引入了 IX/IS,用来表示一个事务想要在某个数据行上加 X 锁或 S 锁。
|
使用意向锁(Intention Locks)可以更容易地支持多粒度封锁。
|
||||||
|
|
||||||
有以下两个规定:
|
在存在行级锁和表级锁的情况下,事务 T 想要对表 A 加 X 锁,就需要先检测是否有其它事务对表 A 或者表 A 中的任意一行加了锁,那么就需要对表 A 的每一行都检测一次,这是非常耗时的。
|
||||||
|
|
||||||
1. 一个事务在获得某个数据行对象的 S 锁之前,必须先获得 IS 锁或者更强的锁;
|
意向锁在原来的 X/S 锁之上引入了 IX/IS,IX/IS 都是表锁,用来表示一个事务想要在表中的某个数据行上加 X 锁或 S 锁。有以下两个规定:
|
||||||
2. 一个事务在获得某个数据行对象的 X 锁之前,必须先获得 IX 锁。
|
|
||||||
|
1. 一个事务在获得某个数据行对象的 S 锁之前,必须先获得表的 IS 锁或者更强的锁;
|
||||||
|
2. 一个事务在获得某个数据行对象的 X 锁之前,必须先获得表的 IX 锁。
|
||||||
|
|
||||||
|
通过引入意向锁,事务 T 想要对表 A 加 X 锁,只需要先检测是否有其它事务对表 A 加了 X/IX/S/IS 锁,如果加了就表示有其它事务正在使用这个表或者表中某一行的锁,因此事务 T 加 X 锁失败。
|
||||||
|
|
||||||
各种锁的兼容关系如下:
|
各种锁的兼容关系如下:
|
||||||
|
|
||||||
| - | X | IX | S | IS |
|
| - | X | IX | S | IS |
|
||||||
| :--: | :--: | :--: | :--: | :--: |
|
| :--: | :--: | :--: | :--: | :--: |
|
||||||
|X |No |No |No | No|
|
|X |NO |NO |NO | NO|
|
||||||
|IX |No |Yes|No | Yes|
|
|IX |NO |YES |NO | YES|
|
||||||
|S |No |No |Yes| Yes|
|
|S |NO |NO |YES | YES|
|
||||||
|IS |No |Yes|Yes| Yes|
|
|IS |NO |NO |YES | YES|
|
||||||
|
|
||||||
|
解释如下:
|
||||||
|
|
||||||
|
- 任意 IS/IX 锁之间都是兼容的,因为它们只是表示想要对表加锁,而不是真正加锁;
|
||||||
|
- S 锁只与 S 锁和 IS 锁兼容,也就是说事务 T 想要对数据行加 S 锁,其它事务可以已经获得对表或者表中的行的 S 锁。
|
||||||
|
|
||||||
## 封锁协议
|
## 封锁协议
|
||||||
|
|
||||||
|
@ -171,9 +184,9 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
|
||||||
| read A=20 | |
|
| read A=20 | |
|
||||||
| | lock-x(A) |
|
| | lock-x(A) |
|
||||||
| | wait |
|
| | wait |
|
||||||
| write A=19 | |
|
| write A=19 |. |
|
||||||
| commit | |
|
| commit |. |
|
||||||
| unlock-x(A) | |
|
| unlock-x(A) |. |
|
||||||
| | obtain |
|
| | obtain |
|
||||||
| | read A=19 |
|
| | read A=19 |
|
||||||
| | write A=21 |
|
| | write A=21 |
|
||||||
|
@ -193,9 +206,9 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
|
||||||
| write A=19 | |
|
| write A=19 | |
|
||||||
| | lock-s(A) |
|
| | lock-s(A) |
|
||||||
| | wait |
|
| | wait |
|
||||||
| rollback | |
|
| rollback | .|
|
||||||
| A=20 | |
|
| A=20 |. |
|
||||||
| unlock-x(A) | |
|
| unlock-x(A) |. |
|
||||||
| | obtain |
|
| | obtain |
|
||||||
| | read A=20 |
|
| | read A=20 |
|
||||||
| | commit |
|
| | commit |
|
||||||
|
@ -213,9 +226,9 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
|
||||||
| read A=20 | |
|
| read A=20 | |
|
||||||
| |lock-x(A) |
|
| |lock-x(A) |
|
||||||
| | wait |
|
| | wait |
|
||||||
| read A=20| |
|
| read A=20| . |
|
||||||
| commit | |
|
| commit | .|
|
||||||
| unlock-s(A) | |
|
| unlock-s(A) |. |
|
||||||
| | obtain |
|
| | obtain |
|
||||||
| | read A=20 |
|
| | read A=20 |
|
||||||
| | write A=19|
|
| | write A=19|
|
||||||
|
@ -224,7 +237,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
|
||||||
|
|
||||||
### 2. 两段锁协议
|
### 2. 两段锁协议
|
||||||
|
|
||||||
加锁和解锁分为两个阶段进行,事务 T 对数据 A 进行读或者写操作之前,必须先获得对 A 的封锁,并且在释放一个封锁之后,T 不能再获得任何的其它锁。
|
加锁和解锁分为两个阶段进行。事务 T 对数据 A 进行读或者写操作之前,必须先获得对 A 的封锁,并且在释放一个封锁之后,T 不能再获得任何的其它锁。
|
||||||
|
|
||||||
事务遵循两段锁协议是保证并发操作可串行化调度的充分条件。例如以下操作满足两段锁协议,它是可串行化调度。
|
事务遵循两段锁协议是保证并发操作可串行化调度的充分条件。例如以下操作满足两段锁协议,它是可串行化调度。
|
||||||
|
|
||||||
|
@ -238,6 +251,17 @@ lock-x(A)...lock-s(B)...lock-s(C)...unlock(A)...unlock(C)...unlock(B)
|
||||||
lock-x(A)...unlock(A)...lock-s(B)...unlock(B)...lock-s(C)...unlock(C)
|
lock-x(A)...unlock(A)...lock-s(B)...unlock(B)...lock-s(C)...unlock(C)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## MySQL 隐式与显示锁定
|
||||||
|
|
||||||
|
MySQL 的 InnoDB 存储引擎采用两段锁协议,会根据隔离级别在需要的时候自动加锁,并且所有的锁都是在同一时刻被释放,这被称为隐式锁定。
|
||||||
|
|
||||||
|
InnoDB 也可以使用特定的语句进行显示锁定:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT ... LOCK In SHARE MODE;
|
||||||
|
SELECT ... FOR UPDATE;
|
||||||
|
```
|
||||||
|
|
||||||
# 四、隔离级别
|
# 四、隔离级别
|
||||||
|
|
||||||
<font size=4> **1. 未提交读(READ UNCOMMITTED)** </font> </br>
|
<font size=4> **1. 未提交读(READ UNCOMMITTED)** </font> </br>
|
||||||
|
@ -267,7 +291,7 @@ lock-x(A)...unlock(A)...lock-s(B)...unlock(B)...lock-s(C)...unlock(C)
|
||||||
|
|
||||||
# 五、多版本并发控制
|
# 五、多版本并发控制
|
||||||
|
|
||||||
(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现提交读和可重复读这两种隔离级别。而未提交读隔离级别总是读取最新的数据行,无需使用 MVCC;可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。
|
多版本并发控制(Multi-Version Concurrency Control, MVCC)是 MySQL 的 InnoDB 存储引擎实现隔离级别的一种具体方式,用于实现提交读和可重复读这两种隔离级别。而未提交读隔离级别总是读取最新的数据行,无需使用 MVCC;可串行化隔离级别需要对所有读取的行都加锁,单纯使用 MVCC 无法实现。
|
||||||
|
|
||||||
## 版本号
|
## 版本号
|
||||||
|
|
||||||
|
@ -287,7 +311,7 @@ InnoDB 的 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回
|
||||||
|
|
||||||
## 实现过程
|
## 实现过程
|
||||||
|
|
||||||
以下过程针对可重复读隔离级别。
|
以下过程针对可重复读(REPEATABLE READ)隔离级别。
|
||||||
|
|
||||||
### 1. SELECT
|
### 1. SELECT
|
||||||
|
|
||||||
|
@ -315,7 +339,7 @@ InnoDB 的 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回
|
||||||
|
|
||||||
### 1. 快照读
|
### 1. 快照读
|
||||||
|
|
||||||
读取快照中的数据,可以减少加锁所带来的开销。
|
这是 MVCC 的一种方式,读取的是快照中的数据,可以减少加锁所带来的开销。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
select * from table ...;
|
select * from table ...;
|
||||||
|
@ -323,7 +347,7 @@ select * from table ...;
|
||||||
|
|
||||||
### 2. 当前读
|
### 2. 当前读
|
||||||
|
|
||||||
读取最新的数据,需要加锁。以下第一个语句需要加 S 锁,其它都需要加 X 锁。
|
读取的是最新的数据,需要加锁。以下第一个语句需要加 S 锁,其它都需要加 X 锁。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
select * from table where ? lock in share mode;
|
select * from table where ? lock in share mode;
|
||||||
|
@ -335,7 +359,7 @@ delete;
|
||||||
|
|
||||||
# 六、Next-Key Locks
|
# 六、Next-Key Locks
|
||||||
|
|
||||||
Next-Key Locks 也是 MySQL 的 InnoDB 存储引擎的一种锁实现。MVCC 不能解决幻读的问题,Next-Key Locks 就是为了解决这个问题而存在的。在可重复读隔离级别下,使用 MVCC + Next-Key Locks 可以解决幻读问题。
|
Next-Key Locks 也是 MySQL 的 InnoDB 存储引擎的一种锁实现。MVCC 不能解决幻读的问题,Next-Key Locks 就是为了解决这个问题而存在的。在可重复读(REPEATABLE READ)隔离级别下,使用 MVCC + Next-Key Locks 可以解决幻读问题。
|
||||||
|
|
||||||
## Record Locks
|
## Record Locks
|
||||||
|
|
||||||
|
@ -615,4 +639,4 @@ Entity-Relationship,有三个组成部分:实体、属性、联系。
|
||||||
- [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 locking for the busy web developer](https://www.brightbox.com/blog/2013/10/31/on-mysql-locks/)
|
||||||
- [浅入浅出 MySQL 和 InnoDB](https://draveness.me/mysql-innodb)
|
- [浅入浅出 MySQL 和 InnoDB](https://draveness.me/mysql-innodb)
|
||||||
- [fd945daf-4a6c-4f20-b9c2-5390f5955ce5.jpg](https://tech.meituan.com/innodb-lock.html)
|
- [Innodb 中的事务隔离级别和锁的关系](https://tech.meituan.com/innodb-lock.html)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user