auto commit

This commit is contained in:
CyC2018 2019-12-07 22:23:08 +08:00
parent 3348b201d1
commit 67e70462af
12 changed files with 28 additions and 114 deletions

View File

@ -47,7 +47,7 @@
事务指的是满足 ACID 特性的一组操作可以通过 Commit 提交一个事务也可以使用 Rollback 进行回滚 事务指的是满足 ACID 特性的一组操作可以通过 Commit 提交一个事务也可以使用 Rollback 进行回滚
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207211851299.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207222237925.png"/> </div><br>
## ACID ## ACID
@ -94,25 +94,25 @@ MySQL 默认采用自动提交模式。也就是说,如果不显式使用`STAR
T<sub>1</sub> T<sub>2</sub> 两个事务都对一个数据进行修改T<sub>1</sub> 先修改T<sub>2</sub> 随后修改T<sub>2</sub> 的修改覆盖了 T<sub>1</sub> 的修改 T<sub>1</sub> T<sub>2</sub> 两个事务都对一个数据进行修改T<sub>1</sub> 先修改T<sub>2</sub> 随后修改T<sub>2</sub> 的修改覆盖了 T<sub>1</sub> 的修改
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207205105044.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207221744244.png"/> </div><br>
## 读脏数据 ## 读脏数据
T<sub>1</sub> 修改一个数据T<sub>2</sub> 随后读取这个数据如果 T<sub>1</sub> 撤销了这次修改那么 T<sub>2</sub> 读取的数据是脏数据 T<sub>1</sub> 修改一个数据T<sub>2</sub> 随后读取这个数据如果 T<sub>1</sub> 撤销了这次修改那么 T<sub>2</sub> 读取的数据是脏数据
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207205339747.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207221920368.png"/> </div><br>
## 不可重复读 ## 不可重复读
T<sub>2</sub> 读取一个数据T<sub>1</sub> 对该数据做了修改如果 T<sub>2</sub> 再次读取这个数据此时读取的结果和第一次读取的结果不同 T<sub>2</sub> 读取一个数据T<sub>1</sub> 对该数据做了修改如果 T<sub>2</sub> 再次读取这个数据此时读取的结果和第一次读取的结果不同
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207210118304.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207222102010.png"/> </div><br>
## 幻影读 ## 幻影读
T<sub>1</sub> 读取某个范围的数据T<sub>2</sub> 在这个范围内插入新的数据T<sub>1</sub> 再次读取这个范围的数据此时读取的结果和和第一次读取的结果不同 T<sub>1</sub> 读取某个范围的数据T<sub>2</sub> 在这个范围内插入新的数据T<sub>1</sub> 再次读取这个范围的数据此时读取的结果和和第一次读取的结果不同
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207210802815.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207222134306.png"/> </div><br>
---- ----
@ -162,17 +162,12 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
各种锁的兼容关系如下 各种锁的兼容关系如下
| - | X | IX | S | IS | <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207214442687.png"/> </div><br>
| :--: | :--: | :--: | :--: | :--: |
| **X** |× |× |× | ×|
| **IX** |× | |× | |
| **S** |× |× | | |
| **IS** |× | | | |
解释如下 解释如下
- 任意 IS/IX 锁之间都是兼容的因为它们只表示想要对表加锁而不是真正加锁 - 任意 IS/IX 锁之间都是兼容的因为它们只表示想要对表加锁而不是真正加锁
- 这里 X/IX/S/IS 锁都是表级锁IX 锁和行级的 X 锁兼容两个事务可以对两个数据行加 X 事务 T<sub>1</sub> 想要对数据行 R<sub>1</sub> X 事务 T<sub>2</sub> 想要对同一个表的数据行 R<sub>2</sub> X 两个事务都需要对该表加 IX 但是 IX 锁是兼容的并且 IX 锁与行级的 X 锁也是兼容的因此两个事务都能加锁成功对同一个表中的两个数据行做修改 - 这里兼容关系针对的是表级锁而表级的 IX 锁和行级的 X 锁兼容两个事务可以对两个数据行加 X 事务 T<sub>1</sub> 想要对数据行 R<sub>1</sub> X 事务 T<sub>2</sub> 想要对同一个表的数据行 R<sub>2</sub> X 两个事务都需要对该表加 IX 但是 IX 锁是兼容的并且 IX 锁与行级的 X 锁也是兼容的因此两个事务都能加锁成功对同一个表中的两个数据行做修改
## 封锁协议 ## 封锁协议
@ -184,20 +179,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
可以解决丢失修改问题因为不能同时有两个事务对同一个数据进行修改那么事务的修改就不会被覆盖 可以解决丢失修改问题因为不能同时有两个事务对同一个数据进行修改那么事务的修改就不会被覆盖
| T<sub>1</sub> | T<sub>2</sub> | <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207220440451.png"/> </div><br>
| :--: | :--: |
| lock-x(A) | |
| read A=20 | |
| | lock-x(A) |
| | wait |
| write A=19 |. |
| commit |. |
| unlock-x(A) |. |
| | obtain |
| | read A=19 |
| | write A=21 |
| | commit |
| | unlock-x(A)|
**二级封锁协议** **二级封锁协议**
@ -205,20 +187,8 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
可以解决读脏数据问题因为如果一个事务在对数据 A 进行修改根据 1 级封锁协议会加 X 那么就不能再加 S 锁了也就是不会读入数据 可以解决读脏数据问题因为如果一个事务在对数据 A 进行修改根据 1 级封锁协议会加 X 那么就不能再加 S 锁了也就是不会读入数据
| T<sub>1</sub> | T<sub>2</sub> | <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207220831843.png"/> </div><br>
| :--: | :--: |
| lock-x(A) | |
| read A=20 | |
| write A=19 | |
| | lock-s(A) |
| | wait |
| rollback | .|
| A=20 |. |
| unlock-x(A) |. |
| | obtain |
| | read A=20 |
| | unlock-s(A)|
| | commit |
**三级封锁协议** **三级封锁协议**
@ -226,26 +196,13 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
可以解决不可重复读的问题因为读 A 其它事务不能对 A X 从而避免了在读的期间数据发生改变 可以解决不可重复读的问题因为读 A 其它事务不能对 A X 从而避免了在读的期间数据发生改变
| T<sub>1</sub> | T<sub>2</sub> | <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207221313819.png"/> </div><br>
| :--: | :--: |
| lock-s(A) | |
| read A=20 | |
| |lock-x(A) |
| | wait |
| read A=20| . |
| commit | .|
| unlock-s(A) |. |
| | obtain |
| | read A=20 |
| | write A=19|
| | commit |
| | unlock-X(A)|
### 2. 两段锁协议 ### 2. 两段锁协议
加锁和解锁分为两个阶段进行 加锁和解锁分为两个阶段进行
可串行化调度是指通过并发控制使得并发执行的事务结果与某个串行执行的事务结果相同 可串行化调度是指通过并发控制使得并发执行的事务结果与某个串行执行的事务结果相同串行执行的事务互不干扰不会出现并发一致性问题
事务遵循两段锁协议是保证可串行化调度的充分条件例如以下操作满足两段锁协议它是可串行化调度 事务遵循两段锁协议是保证可串行化调度的充分条件例如以下操作满足两段锁协议它是可串行化调度
@ -253,7 +210,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
lock-x(A)...lock-s(B)...lock-s(C)...unlock(A)...unlock(C)...unlock(B) lock-x(A)...lock-s(B)...lock-s(C)...unlock(A)...unlock(C)...unlock(B)
``` ```
但不是必要条件例如以下操作不满足两段锁协议它还是可串行化调度 但不是必要条件例如以下操作不满足两段锁协议它还是可串行化调度
```html ```html
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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -47,7 +47,7 @@
事务指的是满足 ACID 特性的一组操作可以通过 Commit 提交一个事务也可以使用 Rollback 进行回滚 事务指的是满足 ACID 特性的一组操作可以通过 Commit 提交一个事务也可以使用 Rollback 进行回滚
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207211851299.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207222237925.png"/> </div><br>
## ACID ## ACID
@ -94,25 +94,25 @@ MySQL 默认采用自动提交模式。也就是说,如果不显式使用`STAR
T<sub>1</sub> T<sub>2</sub> 两个事务都对一个数据进行修改T<sub>1</sub> 先修改T<sub>2</sub> 随后修改T<sub>2</sub> 的修改覆盖了 T<sub>1</sub> 的修改 T<sub>1</sub> T<sub>2</sub> 两个事务都对一个数据进行修改T<sub>1</sub> 先修改T<sub>2</sub> 随后修改T<sub>2</sub> 的修改覆盖了 T<sub>1</sub> 的修改
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207205105044.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207221744244.png"/> </div><br>
## 读脏数据 ## 读脏数据
T<sub>1</sub> 修改一个数据T<sub>2</sub> 随后读取这个数据如果 T<sub>1</sub> 撤销了这次修改那么 T<sub>2</sub> 读取的数据是脏数据 T<sub>1</sub> 修改一个数据T<sub>2</sub> 随后读取这个数据如果 T<sub>1</sub> 撤销了这次修改那么 T<sub>2</sub> 读取的数据是脏数据
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207205339747.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207221920368.png"/> </div><br>
## 不可重复读 ## 不可重复读
T<sub>2</sub> 读取一个数据T<sub>1</sub> 对该数据做了修改如果 T<sub>2</sub> 再次读取这个数据此时读取的结果和第一次读取的结果不同 T<sub>2</sub> 读取一个数据T<sub>1</sub> 对该数据做了修改如果 T<sub>2</sub> 再次读取这个数据此时读取的结果和第一次读取的结果不同
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207210118304.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207222102010.png"/> </div><br>
## 幻影读 ## 幻影读
T<sub>1</sub> 读取某个范围的数据T<sub>2</sub> 在这个范围内插入新的数据T<sub>1</sub> 再次读取这个范围的数据此时读取的结果和和第一次读取的结果不同 T<sub>1</sub> 读取某个范围的数据T<sub>2</sub> 在这个范围内插入新的数据T<sub>1</sub> 再次读取这个范围的数据此时读取的结果和和第一次读取的结果不同
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207210802815.png"/> </div><br> <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207222134306.png"/> </div><br>
---- ----
@ -162,17 +162,12 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
各种锁的兼容关系如下 各种锁的兼容关系如下
| - | X | IX | S | IS | <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207214442687.png"/> </div><br>
| :--: | :--: | :--: | :--: | :--: |
| **X** |× |× |× | ×|
| **IX** |× | |× | |
| **S** |× |× | | |
| **IS** |× | | | |
解释如下 解释如下
- 任意 IS/IX 锁之间都是兼容的因为它们只表示想要对表加锁而不是真正加锁 - 任意 IS/IX 锁之间都是兼容的因为它们只表示想要对表加锁而不是真正加锁
- 这里 X/IX/S/IS 锁都是表级锁IX 锁和行级的 X 锁兼容两个事务可以对两个数据行加 X 事务 T<sub>1</sub> 想要对数据行 R<sub>1</sub> X 事务 T<sub>2</sub> 想要对同一个表的数据行 R<sub>2</sub> X 两个事务都需要对该表加 IX 但是 IX 锁是兼容的并且 IX 锁与行级的 X 锁也是兼容的因此两个事务都能加锁成功对同一个表中的两个数据行做修改 - 这里兼容关系针对的是表级锁而表级的 IX 锁和行级的 X 锁兼容两个事务可以对两个数据行加 X 事务 T<sub>1</sub> 想要对数据行 R<sub>1</sub> X 事务 T<sub>2</sub> 想要对同一个表的数据行 R<sub>2</sub> X 两个事务都需要对该表加 IX 但是 IX 锁是兼容的并且 IX 锁与行级的 X 锁也是兼容的因此两个事务都能加锁成功对同一个表中的两个数据行做修改
## 封锁协议 ## 封锁协议
@ -184,20 +179,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
可以解决丢失修改问题因为不能同时有两个事务对同一个数据进行修改那么事务的修改就不会被覆盖 可以解决丢失修改问题因为不能同时有两个事务对同一个数据进行修改那么事务的修改就不会被覆盖
| T<sub>1</sub> | T<sub>2</sub> | <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207220440451.png"/> </div><br>
| :--: | :--: |
| lock-x(A) | |
| read A=20 | |
| | lock-x(A) |
| | wait |
| write A=19 |. |
| commit |. |
| unlock-x(A) |. |
| | obtain |
| | read A=19 |
| | write A=21 |
| | commit |
| | unlock-x(A)|
**二级封锁协议** **二级封锁协议**
@ -205,20 +187,8 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
可以解决读脏数据问题因为如果一个事务在对数据 A 进行修改根据 1 级封锁协议会加 X 那么就不能再加 S 锁了也就是不会读入数据 可以解决读脏数据问题因为如果一个事务在对数据 A 进行修改根据 1 级封锁协议会加 X 那么就不能再加 S 锁了也就是不会读入数据
| T<sub>1</sub> | T<sub>2</sub> | <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207220831843.png"/> </div><br>
| :--: | :--: |
| lock-x(A) | |
| read A=20 | |
| write A=19 | |
| | lock-s(A) |
| | wait |
| rollback | .|
| A=20 |. |
| unlock-x(A) |. |
| | obtain |
| | read A=20 |
| | unlock-s(A)|
| | commit |
**三级封锁协议** **三级封锁协议**
@ -226,26 +196,13 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
可以解决不可重复读的问题因为读 A 其它事务不能对 A X 从而避免了在读的期间数据发生改变 可以解决不可重复读的问题因为读 A 其它事务不能对 A X 从而避免了在读的期间数据发生改变
| T<sub>1</sub> | T<sub>2</sub> | <div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/image-20191207221313819.png"/> </div><br>
| :--: | :--: |
| lock-s(A) | |
| read A=20 | |
| |lock-x(A) |
| | wait |
| read A=20| . |
| commit | .|
| unlock-s(A) |. |
| | obtain |
| | read A=20 |
| | write A=19|
| | commit |
| | unlock-X(A)|
### 2. 两段锁协议 ### 2. 两段锁协议
加锁和解锁分为两个阶段进行 加锁和解锁分为两个阶段进行
可串行化调度是指通过并发控制使得并发执行的事务结果与某个串行执行的事务结果相同 可串行化调度是指通过并发控制使得并发执行的事务结果与某个串行执行的事务结果相同串行执行的事务互不干扰不会出现并发一致性问题
事务遵循两段锁协议是保证可串行化调度的充分条件例如以下操作满足两段锁协议它是可串行化调度 事务遵循两段锁协议是保证可串行化调度的充分条件例如以下操作满足两段锁协议它是可串行化调度
@ -253,7 +210,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
lock-x(A)...lock-s(B)...lock-s(C)...unlock(A)...unlock(C)...unlock(B) lock-x(A)...lock-s(B)...lock-s(C)...unlock(A)...unlock(C)...unlock(B)
``` ```
但不是必要条件例如以下操作不满足两段锁协议它还是可串行化调度 但不是必要条件例如以下操作不满足两段锁协议它还是可串行化调度
```html ```html
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)