spring事务相关

spring事务

事务的四大特性:

        原子性:事务内的修改操作,要么都成功,要么都失败

        一致性:数据的修改必须正确,保持一致,比如转账 A扣100,那么B必须加100

        隔离性:两个不同的事务间的操作,不能相互影响,事务有四个隔离机制(下面会描述)

        持久性:指的是事务提交后会长久保存,所以数据不能有错

脏读、幻读、不可重复读  (这是事务解决的几种问题):

        脏读:指的是一次读取中,事务A对数据进行修改但是未提交,事务B读取了这条数据,但是事务A回滚,导致事务B读取了错误数据。

        幻读:指的是两次读取,侧重点在于新增删除,事务A第一次读取数据,同时事务B对数据进行了新增或删除,事务A第二次读取这批数据时和第一次读有出入。

        不可重复读:指的是两次读取,侧重点在于修改,事务A第一次读取数据,同时事务B对数据进行了修改,导致事务A两次读取的数据不一致。

事务的隔离级别(四种):

        读未提交:当前事务可以读取其他事务修改但是未提交的数据

                解决:一般不会使用,什么问题也解决不了

        读已提交:当前事务可以读取其他事务修改并且已经提交的数据

                解决:可以解决脏读

        可重复读:当前事务在读取数据的时候会加上锁,让其他事务不能对当前数据修改。

                解决:可以解决脏读,不可重复读

        串行化:隔离级别最高的,让所有事务有顺序的执行,A事务执行完B事务再执行

                解决:可以解决脏读、幻读、不可重复读问题,但是相对的执行效率会降低

2类事务丢失:

        第一类:问题由多个事务间同时操作的回滚所导致,事务A和B共同修改age=10这条数据,事务A将age修改为20,在还没有提交的时候事务B也来操作,此时事务B拿到的还是age=10,因为undolog日志文件保存的还是事务A提交前的数据,此时事务A提交了事务,数据库数据变成了20,然后事务B运行过程报错,触发回滚,将数据改成了10,导致事务A修改操作无意义。

        第二类:问题由多个事务同时操作数据导致,还是刚才的例子,事务A将数据修改为20,在提交前事务B也来修改,然后事务A提交,数据落地为20,然后事务B读取到的依然是10,此时事务B对数据操作并且提交,导致事务A的操作无意义。

        区别则在于:一个是回滚导致A无效,一个是共同操作数据导致A无效。

@Transactional事务失效场景

        用在被final、static修饰的方法上会失效:

        由于spring事务会基于spring的动态代理来实现,通常使用到的是CGLIB动态代理,而这种动态代理方式会创建目标类的子类来实现,所以会导致动态代理无法继承目标方法。

        非public 的方法会失效:

        在事务底层代码中明确说明无法作用域非public方法。

        多线程调用可能失效:

        线程A指定线程B去执行新增数据,等线程B执行完毕后主线程A还是读不到新增的数据,那是因为不同线程处于两个不同的事务当中。

        抛出的异常错误:

        默认情况下@transactional会捕获runtimeException,如果其他异常会捕获不了所以失效,可以通过添加注解属性,rollbackFor = Exception.class 指定异常可以解决这问题

        配合try catch使用:

        如果在catch中只捕获异常却没有抛出异常也会失效,解决方式两种:1.抛出runtime异常让事务注解捕获。2.在catch中手动触发回滚方法

        

分布式事务:

        2PC协议(两阶段提交)

        1.应用程序通过事务协调器向两个服务同时发送通知,a和b同时开始执行各自本地事务,执行完了不提交事务给事务协调器返回yes或者no

        2.如果两个事务返回的都是yes,那么发送指令让两个事务都提交事务,如果其中一方提交失败那么返回通知协调器,由协调器通知另一方也回滚

        3.如果参与者中有返回no的,都直接回滚

        消息队列完成最终事务一致

        举例a服务新增订单b服务减少库存的例子

        1.a服务完成自己本地事务,添加订单操作,并且在消息表中添加一条“减少库存”的消息

        2.专门有定时任务检查消息表中的数据,并且取出来发给mq给到b消费

        3.b收到减少库存的消息开始执行减少库存操作,并且在本地记录表新增“减少库存信息”(在每次减少库存前都会检查一遍记录表,是否执行过这个减少库存,如果执行过了就不要再执行)

        4.b执行完了会给mq发送一条“库存减少”消息

        5.a收到了“库存减少”消息后会删除消息表中的“减少库存”消息

        如果b失败定时任务会不断给b发送重试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值