ACID
原子性(Atomicity)
事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务前后数据的完整性必须一致。
隔离性(Isolation)
事务之间要相互隔离。
持久性(Durability)
事务一旦提交,数据必须持久化且不受任何因素影响。
脏读、幻读、不可重复读
脏读
事务A读取到事务B未提交的数据
不可重复读
事务A中两次读取的数据内容不一致
幻读
事务A两次读取的数据数量不一致
mysql隔离级别和脏读、幻读、不可重复读的关系
| 脏读 | 不可重复读 | 幻读 |
读未提交 | √ | √ | √ |
读提交 | × | √ | √ |
可重复读 | × | × | √ |
可串行化 | × | × | × |
读未提交
事务可读取到其他事务未提交的数据,故脏读、幻读、不可重复读均可能发生
读提交
事务可读取到其他事务已提交的数据,故脏读不再发生
不可重复读场景1:
事务A查询记录1得到money=1
事务B修改记录1的money=2事务B提交
事务A查询记录1得到money=2
幻读场景2:
事务A查询表1得到总行数为1
事务B新增一条记录事务B提交
事务A查询表1得到的总行数为2
因此隔离级别为读提交时,还是会发生不可重复读或幻读
可重复读
事务读取时创建一个快照,事务多次读取时,数据从创建中的快照中获取,故不可重复读不再发生
但因快照只能快照当前已有数据,故幻读的场景无法避免
可串行化
严格案遭事务的顺序执行,故不存在脏读、幻读、不可重复读
MVCC 多版本并发控制
每个事务都会生成递增的版本号,mysql的每条数据都有各自隐藏的新增、删除事务版本号字段。
新增、修改会将当前事务的版本号赋值给该行数据的新增版本号
删除会将当前事务的版本号赋值给该行数据的删除版本号
每个事务只能查询
新增版本号<当前事务版本号 (创建在事务启动前)
且
删除版本号为空或>当前事务版本号 (删除在事务启动后)
的数据
场景如下:
事务A开启,版本号为1001
事务B开启,版本号为1002
事务A第一次查询表1得到总行数为100
事务B新增了10条记录
事务B提交,新增的10条记录的新增版本号为1002
事务A第二次查询表1得到的总行数为100