目录,更新ing,学习Java的点滴记录
目录放在这里太长了,附目录链接大家可以自由选择查看--------Java学习目录
Spring知识
一丶SpringIOC初步认识↓↓↓
第一篇---->初识Spring
二丶SpringIOC深入↓↓↓
第二篇---->深入SpringIoC容器(一)
第三篇---->深入SpringIoC容器(二)
三丶装配SpringBean↓↓↓
第四篇---->依赖注入的方式
第五篇---->基于xml装配Bean
第六篇---->基于注解装配Bean
第七篇---->Spring Bean之间的关系
第八篇---->SpringBean的作用域
第九篇---->Spring 加载属性(properties)文件
第十篇---->Spring表达式(SpEL)
第十一篇---->Spring在xml中配置组件扫描
四丶面向切面编程↓↓↓
第十二篇—>认识SpringAOP及底层原理
第十三篇—>使用@AspectJ注解开发AOP
第十四篇—>使用xml配置开发AOP
五丶Spring中数据库编程↓↓↓
第十五篇—>数据库编程JdbcTemplate
六丶Spring事务管理↓↓↓
第十六篇—>Spring事务管理初识
第十七篇—>编程式事务和声明式事务
第十八篇—>事务ACID特性
第十九篇—>事务传播行为
第二十篇—>事务隔离级别
6.3 隔离级别
6.3.1 丢失更新
- 互联网应用中存在抢购,秒杀等高并发场景,使得数据库在一个多事务的环境中运行,多个事务的并发会产生一系列问题,主要的问题之一就是丢失更新,一般而言存在两类丢失更新
- 假设一个场景,一个账户存在两种消费形式,刷卡和互联网消费,A和B共用这一个账户,A使用刷卡,B使用互联网消费,下面是一种场景
- 整个过程中只有A消费了1000,但是在T6时刻,B回滚事务,恢复了原来的余额10000,这显然不符合事实.这样的两个事务并发,一个回滚,一个提交成功导致不一致,称为第一类丢失更新.但是目前大部分数据库MySQL,Oracle等已经消灭了这类丢失更新.
- 第二类丢失更新时更重要的,新的场景如下
- 整个过程中两者都提交了事务,但是由于是不同的事务,无法探知其他事务的操作,导致两者提交后,余额都为9000,而实际应该为8000,这就是第二类丢失更新.
- 为了克服事务之间的一致性,定义了事务之间的
隔离级别
,来在不同程度上减少出现丢失更新的可能性.
6.3.1 隔离级别概念
- 隔离级别可以在不同程度上减少丢失更新,按照SQL的标准,将隔离级别
定义为4层
,分别是:脏读未提交(read uncommitted),读已提交(read committed),可重复读(repeatable read)和序列化(Serializable)
,它们在不同程度上解决了脏读,不可重复读,幻读
问题.
6.3.2 脏读,不可重复读,幻读
- 脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但 还没有被提交的字段. 之后, 若 T2 回滚, T1读取的内容就是临时且无效的.
- 不可重复读:对于两个事物 T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了.
- 幻读:对于两个事物 T1, T2, T1 从一个表中读取了几行记录, 然后 T2 在该表中插入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行.
6.3.3 四种隔离级别
读未提交是最低的隔离级别,含义是允许一个事务去读取另一个事务未提交的数据
由于在T3时刻,B消费了1000,导致余额为9000,A在T4时刻消费,因为用了读未提交
,所以能够读取到B消费的余额(这个余额此时是B未提交的)为9000,这样余额就变成了8000,T5时刻A提交事务,余额变为8000,B在T6时刻回滚事务,由于数据库已经克服了第一类丢失更新,所以余额依旧为8000,显然这是错误的.产生这个错误的根源在于T4时刻,也就是A读取了B未提交的事务,称为脏读
.读已提交是说一个事务只能读取另一个事务已经提交的数据.
T3时刻,由于事务采取读已提交的隔离级别,A无法读取到B未提交的9000元月,只能读到余额为10000,所以消费后余额依旧为9000.T5时刻A提交事务,而T6时刻B回滚事务,结果为9000,这样就消除了脏读带来的问题
,但是也会引发其他问题,如下图
T7时刻A知道B提交的结果余额为1000,结果无法提交,A并不清楚B做了什么,但是余额莫名其妙的从10000变成了1000,对A来说余额是不能重复读取的,是一个会变化的值,这样的场景称为不可重复读,这是读已提交存在的问题
.可重复读,针对数据库中同一条记录而言,使得同一条数据库记录的读写按照一个序列化进行操作,不会产生交叉情况,这样就能保证同一条数据的一致性.
但是很多场景下,并非只对一条记录读写,很多都是对多条记录读写,这时候就会产生下面的情况
序列化是一种让SQL按照顺序读写的方式,能够消除数据库事务之间并发产生数据不一致的问题.
序列化可以克服幻读的问题.
6.3.4 隔离级别及其可能产生的问题表
6.3.5 Spring支持的事务隔离级别
- 图示
- 事务的隔离级别要得到
底层数据库引擎的支持
, 而不是应用程序或者框架的支持 - Oracle 支持的 2 种事务隔离级别:READ_COMMITED , SERIALIZABLE,
默认是READ_COMMITED
- MySQL支持4种事务隔离级别:READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE,
默认是REPEATABLE_READ
6.3.6 @Transactional设置事务隔离级别
- 用 @Transactional 注解声明式地管理事务时可以在 @Transactional 的 isolation 属性中设置隔离级别.