一、事务隔离级别
事务的隔离级别有三种:脏读、幻读、不可重复读
1.脏读(也叫读未提交)
一个事务读到另一个事务未提交的内容
有一个很典型的例子,银行取钱问题。
事务A开启了取钱事务,
——> 切换到事务B,事务B开启了转账事务,
——>切换到事务A,账户里有200块钱,事务A取出100块钱,此时账户里余额为100,
——>切换到事务B,事务B查询到账户里余额为100
——>切换到事务A,A遇到某种错误,事务回滚,余额又变回200元,
——>切换到事务B,事务B往账户里存了300块,将账户余额变更为100+300=400元,提交事务
此时,就发生问题了,正确来讲,此时余额应该为200+300=500元
如何解决脏读呢?使用读已提交
2.幻读
当事务不是独立执行时发生的现象:前后多次读取,数据总量不一致
事务A进行读取总量操作
——> 切换到事务B,事务B执行插入数据操作并提交
——>切换到事务A,事务A再次进行读取总量操作
事务A前后两次读取的数据总量不一样,就像发生了幻觉一样
3.不可重复读
在一个事务里面的操作中发现了未被操作的数据:前后多次读取,数据内容不一致
事务A进行读取操作,由于整个事务A比较庞大,执行完事务A需要时间很长,第一次读取时,账户里有100块钱
——> 切换到事务B,事务B向账户里存了100块钱,且提交事务
——>切换到事务A,事务A再次读取账户余额,获取到的余额为200块
按照正确逻辑,事务A前后读取到的数据应该是一样的,但事务A前后读到的数据不一样,不重复了,系统不能读到重复的数据,称为不可重复读。
如何解决不可重复读呢?使用可重复读
二、Spring支持的隔离级别
事务的隔离级别有五种:默认、读未提交、读已提交、可重复读、串行化
1.默认(DEFAULT)
使用数据库本身使用的隔离级别
ORACLE(读已提交) MySQL(可重复读)
2.读未提交(READ_UNCOMITTED)
读未提交可能会产生:脏读、幻读、不可重复读的问题
3.读已提交(READ_COMMITED)
读已提交指的是:一个事务在进行读取操作时,不读取其它事务未提交的内容,只读取已提交的内容。这样就解决了脏读所产生的问题。
读已提交可能会产生:幻读、不可重复读的问题
4.可重复读(REPEATABLE_READ)
可重复读指的是:一个A事务在进行读取操作时,不允许其它事务来修改A事务所读取的对象,这样就解决了不可重复读和脏读所产生的问题。
可重复读可能会产生:幻读的问题
5.串行化(SERLALIZABLE)
串行化,最高的事务隔离级别,不管多少事务,挨个运行完一个事务的所有子事务之后才可以执行另外一个事务里面的所有子事务,这样就解决了脏读、不可重复读和幻读的问题。
参考文章:
https://blog.csdn.net/qq_33591903/article/details/81672260
https://blog.csdn.net/qq_38526573/article/details/87898730