MySQL事务
提到事务,肯定可以想到 ACID 特性,ACID 指的是什么呢?
- Atomicity(原子性)
一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务如果在过程中发生错误,就会被回滚到事务开始前到状态,就像事务从来没有执行过一样。
- Consistency(一致性)
在事务开始之前和事务结束之后,数据库的完整性没有被破坏。表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
- Isolation(隔离性)
数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
- Durability(持久性)
事务一旦提交,对数据的修改是永久的,即便系统故障也不会丢失。
事务隔离级别
SQL 标准中定义了四种隔离级别,一般来说,隔离级别越低,系统开销越低,可支持的并发越高,但隔离性也越低。隔离级别与读问题的关系如下:
隔离级别 | 脏读 | 不可重复度 | 幻读 |
---|---|---|---|
Read Uncommitted 读未提交 | 可能 | 可能 | 可能 |
Read Uncommitted 读已提交 | 不可能 | 可能 | 可能 |
Repeatable Read 可重复读 | 不可能 | 不可能 | 可能 |
Serilalizable 可串行化 | 不可能 | 不可能 | 不可能 |
InnoDB 默认的隔离级别是 RR ,在 SQL 标准中, RR 无法避免幻读问题,但是 InnoDB 实现的 RR 避免了幻读问题。
脏读
当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据),这种现象是脏读。
举例如下(以账户余额表为例):
时间 | 事务A | 事务B |
---|---|---|
T1 | 开始事务 | 开始事务 |
T2 | 修改zhangsan余额,将余额由100改为200 | |
T3 | 查询zhangsan余额,结果为200【脏读】 | |
T4 | 提交事务 |
不可重复读
在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。
举例如下:
时间 | 事务A | 事务B |
---|---|---|
T1 | 开始事务 | 开始事务 |
T2 | 查询zhangsan余额,结果为100 | |
T3 | 修改zhangsan余额,将余额由100改为200 | |
T4 | 提交事务 | |
T5 | 查询zhangsan余额,结果为200【不可重复读】 |
幻读
在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。
举例如下:
时间 | 事务A | 事务B |
---|---|---|
T1 | 开始事务 | 开始事务 |
T2 | 查询 0 < id < 5 的所有用户的余额:zhangsan:100(id=1) | |
T3 | 账户余额表中插入新用户 lisi: 200(id=2) | |
T4 | 提交事务 | |
T5 | 查询 0 < id < 5 的所有用户的余额:zhangsan:100(id=1)lisi:200(id=2)【幻读】 |
- 本文链接: https://lemonlyue.github.io/2024/07/28/MySQL事务/
- 版权声明: 本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。