事务隔离等级:
@Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交的数据(会出现脏读, 不可重复读) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED):读取已提交的数据(会出现不可重复的阅读和幻读)
@Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)
@Transactional(isolation = Isolation.SERIALIZABLE):串行化
1.READ UNCIMMITTED(未提交阅读)
事务中的修改,即使没有提交,也可以看到其他事务。例如,上述两个步骤称为脏阅读。这种隔离水平会导致许多问题。如果没有必要,不要随意使用
例子:或者售票系统,小明和小华是售票员,他们是两个不同窗口的员工,现在只剩下售票系统了3张票,此时A来小华这里买吧3张票,B来小明买票的时候,小华找到了余票,接到了订单,第三步就要执行了。小明收到了B查询是否有余票。看到小华卖了3张票,所以他拒绝卖票。然而,小华系统出了问题,第三步失败了。为了保证原子性,数据库回滚了数据,也就是说,一张票没有卖出去。
总结:这是事务尚未提交,其他事务可以看到其中修改数据的后果,即脏读。
2.READ COMMITTED(提交读)
大多数数据库系统的默认隔离水平是READ COMMITTED,这种隔离水平是事务的开始,只能看到已完成的事务的结果,正在执行的事务,不能被其他事务看到。这个级别会读取旧数据
例子:还是小明小华的销售员,余票3张,A向小华请求3小华接受订单,想卖掉订单3在执行上述销售步骤时,张票,B也来小明买票,因为小华的销售事务执行到一半,小明的事务没有看到小华的事务执行,读到的票数是3,在准备接受订单时,小华的销售事务完成了,小明的系统变成了显示0张开票,小明刚想按下鼠标,点击接受订单的手,迅速缩回。
总结:这是小华事务执行的一半,小明看不到他执行的操作,所以他看到的是旧数据,也就是无效的数据
3.REPEATABLE READ(可重复读)
REPEATABLE READ解决了脏读的问题,这个级别保证了每行记录的结果是一致的,也就是上面提到的读旧数据的问题,但是不能解决另一个问题。幻觉,顾名思义,就是突然跳出来的行数据。指的是一个事务在读取一定范围内的数据,而另一个事务则将数据插入这个范围内的数据,导致数据的行数在多次读取时不一致。
例子:销售部门规定,如果销售记录低于规定值,扣除工资,经理在后端控制台检查小明销售记录,发现销售记录不能达到规定次数,快乐,准备打印销售清单,小明提出,意外打印发现销售清单增加了几个,只是满足要求,煤气经理撕下清单纸。原来小明在即将打印的瞬间卖了几张票,所以避免了减薪的灾难。
总结:虽然读取相同的数据可以保证一致性,但不能保证不插入新数据
4.SERIALIZABLE(可串行化)
SERIALIZABLE它是最高的隔离级别。它通过强制事务串行实施(注意串行),避免了之前的幻读。由于他添加了大量的锁,导致大量的要求加班,因此性能将相对较低。当数据一致性和并发量不需要那么大时,特别需要考虑这个隔离级别
脏读 :所谓脏读,其实就是在其他事务回滚之前读到脏数据。例如,数据X在事务B执行过程中被修改。在提交之前,事务A读取X,但事务B回滚,使事务A形成脏读。
不可重复读 :不能重复阅读的字面含义已经很清楚了。例如,当事务A先读取数据,然后执行逻辑时,事务B会改变数据,然后当事务A再次读取时,发现数据不匹配,这就是所谓的不能重复阅读。
幻读 :小时候数手指,第一次数110个,第二次数11个。怎么回事?产生幻觉?
幻读也是如此。事务A首先根据条件索引获得10个数据,然后事务B改变数据库中的一个数据,导致当时事务A的搜索条件。这样,事务A再次搜索,发现有11个数据,导致幻读。