数据隔离
存在问题
脏读(如有事务A和B,A读取了B未提交的数据)
不可重复读(如有事务A和B,A负责读取,B负责写入,A连续读的过程中B写入了一次,A前后两次读出来的数据不一样) 不可重复读对应的是修改,即UPDATE操作。
丢失更新(如有事务A和B,AB均写入数据,A写入的数据被B覆盖)
幻读(如有事务A和B,A修改表内数据的过程中,B向表内插入了一条数据,A修改完后发现数据并没有被全部修改完) 幻读问题对应的是插入INSERT操作或DELETE操作
子主题 2
隔离级别
.READ UNCIMMITTED(未提交读)
- 事务中的修改,即使没有提交,其他事务也可以看得到,比如说上面的两步这种现象就叫做脏读,这种隔离级别会引起很多问题,如无必要,不要随便使用
- 例子:还是售票系统,小明和小花是售票员,他们分别是两个不同窗口的员工,现在售票系统只剩下3张票,此时A来小华这里买3张票,B来小明买票,小华查到余票还有就给接了订单,就要执行第三步的时候,小明接到B的请求查询有没有余票。看到小华卖出了3张票,于是拒绝卖票。但是小华系统出了问题,第三步执行失败,数据库为保证原子性,数据进行了回滚,也就是说一张票都没卖出去。
- 总结:这就是事务还没提交,而别的事务可以看到他其中修改的数据的后果,也就是脏读。
READ COMMITTED(提交读)禁止脏读
- 大多数数据库系统的默认隔离级别是READ COMMITTED,这种隔离级别就是一个事务的开始,只能看到已经完成的事务的结果,正在执行的,是无法被其他事务看到的。这种级别会出现读取旧数据的现象
- 例子:还是小明小华销售员,余票3张,A来小华那里请求3张订票单,小华接受订单,要卖出3张票,上面的销售步骤执行中的时候,B也来小明那里买票,由于小华的销售事务执行到一半,小明事务没有看到小华的事务执行,读到的票数是3,准备接受订单的时候,小华的销售事务完成了,此时小明的系统变成显示0张票,小明刚想按下鼠标点击接受订单的手又连忙缩了回去。
- 总结:这就是小华的事务执行到一半,而小明看不到他执行的操作,所以看到的是旧数据,也就是无效的数据
REPEATABLE READ(可重复读)禁止脏读和不可重复读
- REPEATABLE READ解决了脏读的问题,该级别保证了每行的记录的结果是一致的,也就是上面说的读了旧数据的问题,但是却无法解决另一个问题,幻行,顾名思义就是突然蹦出来的行数据。指的就是某个事务在读取某个范围的数据,但是另一个事务又向这个范围的数据去插入数据,导致多次读取的时候,数据的行数不一致。
- 例子:销售部门有规定,如果销售记录低于规定的值,要扣工资,此时经理在后端控制台查看了一下小明的销售记录,发现销售记录达不到规定的次数,心里暗喜,准备打印好销售清单,理直气壮和小明提出,没想到打印出来的时候发现销售清单里面销售数量增多了几条,刚刚好达到要求,气的经理撕了清单纸。原来是小明在就要打印的瞬间卖出了几张票,因此避过了减工资的血光之灾。
- 总结:虽然读取同一条数据可以保证一致性,但是却不能保证没有插入新的数据
SERIALIZABLE(可串行化)禁止脏读、不可重复读和幻读
- SERIALIZABLE是最高的隔离级别,它通过强制事务串行执行(注意是串行),避免了前面的幻读情况,由于他大量加上锁,导致大量的请求超时,因此性能会比较底下,再特别需要数据一致性且并发量不需要那么大的时候才可能考虑这个隔离级别