Spring框架(事务隔离级别)

目录,更新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 属性中设置隔离级别.
      在这里插入图片描述
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值