Mysql事务四个特性(ACID):
原子性:一个事务是个整体,不可分割;
一致性:一个事务内的所有sql语句要么一起执行,要么都不执行,
隔离性:事务A和事务B不会互相打扰;
持久性:事务A commit提交完成后,就会被写入数据库,无法rollback回滚;
事务隔离性体现在四个隔离级别:
- 读未提交。
- 读已提交。
- 可重复读。
- 串行化。
隔离级别与对应问题
脏读 | 不可重复读 | 幻读 | |
读未提交 | √ | √ | √ |
读已提交 | √ | √ | |
可重复读 | √ | ||
串行化 |
各个隔离级别具体情景:
隔离级别为【1读未提交】情况下发生的问题:
【
A 用户使用begin开始事务,然后执行插入语句(此时未执行commit提交语句,代表事务还未执行完成)
B用户在A未提交时,使用了select语句,竟然能查看到A插入的数据。
】
脏读:B读取到A未提交的数据。
隔离级别为【2读已提交】情况下发生的问题:
【
A用户使用begin开始事务,然后执行插入语句(此时未执行commit提交语句,代表事务还未执行完成)
B用户在A未commit提交时,begin开始自己的事务,使用了select语句,B用户现在看不到A插入的数据,以为就1条数据。
A用户此时执行commit,数据库才能搜到A用户插入的数据,但是B还不知道
B快下班了,想要commit提交自己的事务,不过为了保险,重新执行select语句想查看数据,发现多了好多数据,又得加班
】
不可重复读:B在一个事务中,使用了多次搜索语句,每次结果都不一样。
隔离级别为【3可重复读】情况下发生的问题:
【
A用户使用begin开始事务,然后执行插入语句(此时未执行commit提交语句,代表事务还未执行完成)
B用户在A未commit提交时,begin开始自己的事务,这次B使用insert插入语句,B用户发现插入失败,数据库提示说,此位置非空,可这位置看起来明明没东西
】
幻读:B在一个事务中,使用插入语句,提示此位置非空,存在着你看不到的数据。
隔离级别为【4串行化】情况下发生的问题:
【
A用户使用begin开始事务(此时未执行commit提交语句,代表事务还未执行完成)
B用户在A未commit提交时,begin开始自己的事务,B使用insert插入语句,B用户发现数据库没有任何反馈,好像卡死了
A用户此时使用commit提交语句
B用户突然发现插入成功了
】