单个事务满足ACID;
读未提交 read uncommitted | 读提交 read committed | 不可重复读 read repeatable | 序列化 serializable | |
---|---|---|---|---|
脏写 dirty write | ||||
脏读 dirty read | √ | √ | √ | |
不可重复读 Non-Repeatable Read | √ | √ | ||
幻读 Phantom | √ |
各级别均是在事务并发执行时的可能发生的场景.
脏写
操作 | 事务A | 事务B |
---|---|---|
a=2 | ||
A-1 | 写a=3 未提交 | |
B-1 | 写a=4 | |
此时 如果 事务A中a=4, 就是脏写. | ||
commit | 无论是A还是B commit ,a的值都是4;(脏写) |
事务A,事务B 同时更新数据 a.
通常后写的能覆盖已提交的先写的.
但(事务B)后写的能否覆盖未提交先写的,能就是脏写;
脏读
操作 | 事务A | 事务B |
---|---|---|
a=2 | ||
A-1 | 写 a=3 未提交 | |
B-1 | 读 a=3 | |
此时,事务B能读到a=3就是脏读; |
事务B读到事务A未提交的数据.
读a = 2 就不是脏读
一个事务A已经写入数据,但未提交,事务B能看到新写入数据吗? 能看到就是脏读
脏读,脏写总结
- 从数据库读时,只能看到已提交的数据;
- 向数据库写时,只能覆盖已提交的数据;
- 多事务并发写,先写需要加行写锁;(应对脏写,脏读策略)
不可重复读
事务先后读到
操作 | 事务A | 事务B |
---|---|---|
a=2 | ||
B-1 | 读 a=2未完成(读未提交) | |
A-1 | 写 a=3; | |
A-2 | Commit | |
B-2 | 读 a=3 |
因B-1 未上读锁,导致事务B在读取中,事务A写入了数据;
脏读和不可重复读区别
数据 | 锁 | |
---|---|---|
脏读 | 读到未提交数据 | 未加写锁 |
不可重复读 | 读到已提交数据 | 未加读锁 |
幻读
操作 | 事务A | 事务B |
---|---|---|
1.1销售额 1w | ||
A-1 | 读 ,统计1.1销售额 = 1w (10条数据) | |
B-1 | 写,增加1.1售出衣服一件 ;commit | |
A-2 | 读 ,统计1.1销售额 = 2w (11条数据) | |
1.1销售额 2w |
事务B先后统计表范围内数据,事务A在之间怎加了一条行记录;
这是锁粒度不同(行锁,表锁)造成的;
相当于事务B只加了10条行锁,未加表锁