事务复习1-理论基础

发布时间:2024年01月24日


已更新完—有需要补充的或者错误请在评论区指出,我会积极而定改正补充学习

事务

特性ACID

1.原子性
2.一致性
3.隔离性
4.持久性

特性解释
原子性A是指事务是一个不可分割的工作单位,事务的操作要么都发生,要么都不发生。
一致性C事务必须从一个一致性的状态变成另外一个一致性的状态
隔离性I一个事务的执行不能被其他事务干扰,并发的执行的各个事务之间不能相互影响
持久性D事务一旦提交,它数据库中数据的改变是永久的。

隔离级别

1.读已提交
读取其他事务已经提交的数据
2.读未提交
读取其他事务还未提交的数据–可能出现脏读
3.可重复读
同一个事务多次读取同一个数据,尽可能的保证数据的一致性但是可能出现幻读
4.串行读
确保每个事务读取的都是最新的数据,但是他的并发是最低的

隔离级别脏读不可重复读幻读
读已提交
读未提交
可重复读
串行读

传播行为Propagation

1.REQUIRED(有就加入,没有就开)
如果当前没有事务,就会新建一个事务,如果当前已经存在一个事务就会加入到这个事务中,这个是默认的事务传播机制
2.SUPPORTS(有就加入,没有就不开)
如果当前存在事务,则会加入事务,如果当前没有事务则是以非事务的方式继续进行
3.MANDATORY(有就加入,没有就抛出异常)
如果当前存在事务,则会加入事务,如果当前没有事务则抛出异常
4.REQUIRES_NEW(必须开启一个事务,不管有没有都会开一个新的事务)
表示创建一个新的事务,如果对当前存在事务,则把当前的事务挂起,也就是说不管外部方法是否开启事务,这里的内部方法都是会开启新的事务,并且开启的事务之间都是相互独立的互不干扰
5.NOT_SUPPORTED(有就挂起)
以非事务进行运行,如果当前存在事务就将当前的事务进行挂起
6.NEVER(有就抛出异常)
以非事务进行运行,如果当前存在事务则会抛出异常
7.NESTED
嵌套事务,如果调用方法已经有了一个事务,那么当前的方法将会嵌套再该事务中执行,如果当前调用的方法没有事务,那么当前的方法将会开启一个新的事务

传播行为当前有事务当前没有事务
PROPAGATION_REQUIRED加入这个事务开启新的事务
PROPAGATION_SUPPORTS加入这个事务以非事务执行
PROPAGATION_MANDATORY加入这个事务抛出异常
PROPAGATION_REQUIRES_NEW当前事务挂起,创建一个新的事务开启新的事务
PROPAGATION_NOT_SUPPORTED当前事务挂起以非事务执行
PROPAGATION_NEVER否抛出异常以非事务执行
PROPAGATION_NESTED在嵌套事务内执行按照REQUIRED方式执行事务

失效情况

1.spring事务会在除了使用公共的public的方法上使用的时候会失效
2.如果方法是被fina或者staticl进行修饰的时候也是导致事务的失效的,原因是事务使用的是动态代理进行实现的如果使用了final进行修饰的时候就会导致事务里面的动态代理无法进行重写导致事务的失效
3.如果被try catch捕获或者报错被抛出的时候也是会导致事务的失效的’’
4. 多线程调用的时候也是会导致事务的失效,原因是spring的事务是和数据库进行连接的,同一个事务只能使用同一个数据库的连接,再多线程的场景下拿到的数据库的连接是不一样的所以不支持事务
5.使用了错误的传播行为例如Propagation.NOT_SUPPORTED也是不支持事务的
6.使用的是不支持事务的存储引擎,例如使用的是mysql的MyISAM
7.数据源没有进行配置事务管理器-----但是springboot框架里面使用的是默认开启了事务
8.调用的是本类的方法也是会导致事务的失效,主要是因为spring的事务是通过aop进行实现的,调用的本类的方法实际上是没有走代理的,所以无法进行增强也就是无法使用事务
9.service没有托管给spring也就是不是spring的bean所以也是会导致事务的失效

案例:后续进行补充

解决方法:

1.非public方法
1). 将方法改为public进行修饰
2). 修改TansactionAttributeSource,将publicMethodsOnly改为false


2.调用本类方法 解决方法:
1). 注入自己来进行调用
2). 使用@EnableAspectJAutoProxy(exposeProxy = true) + AopContext.currentProxy()

分布式事务

CAP理论

类别解释说明
一致性C在分布式系统中所有的节点看到的数据都是相同的,系统的状态再任何时刻都是一致的
可用性A系统不需保证再任何时刻都能处理请求返回正确的结果,即系统一致处于可用的状态
分区容错性P系统再遇到网络分区故障的时候仍然能够保证正常的工作,即系统能够容忍任意数量的消息丢失或网络分区

在这里插入图片描述

为什么CAP不可兼得
这是因为在分布式系统中,网络分区是不可避免的,然而保证一致性和可用性就需要对网络的分区进行取舍衡量


例如:当网络分区发生的时候,节点之间可能无法进行一致性的数据同步,因此在这种情况下,要么保证可用性,允许节点继续处理请求并且返回不一致的结果,要么保证一致性,暂停服务知道网络分区恢复

策略放弃说明
CA放弃容错性适用于小规模的集中式系统
CP放弃可用性适用于对数据一致性比较高的系统,如金融系统
AP放弃一致性适用于对数据实时性要求比较高的系统,如社交网络

BASE理论

这里指的是对CAP中AP的一种拓展,即使无法做到强一致性,但每个应用都可以根据自身业务特点采用适当的方式来使系统达到最终一致性

类别解释说明
Basically Available(基本可用)响应时间上的损失:正常情况下,处理用户请求需要0.5s返回结果,但是由于系统出现故障,处理用户请求的时间变成3s。 系统功能上的损失:正常情况下,用户可以使用系统的全部功能,但是由于系统访问量突然剧增,系统的非核心功能无法使用。
Soft state(软状态)数据同步允许一定的延迟。
Eventually consistent(最终一致性)系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态,不要求实时

最终一致性

类别解释说明
因果一致性(Causal consistency)如果节点 A 在更新完某个数据后通知了节点 B,那么节点 B 之后对该数据的访问和修改都是基于 A 更新后的值。于此同时,和节点 A 无因果关系的节点 C 的数据访问则没有这样的限制。
读己之所写(Read your writes)节点 A 更新一个数据后,它自身总是能访问到自身更新过的最新值,而不会看到旧值。其实也算一种因果一致性。
会话一致性(Session consistency)会话一致性将对系统数据的访问过程框定在了一个会话当中:系统能保证在同一个有效的会话中实现 “读己之所写” 的一致性,也就是说,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。
单调读一致性(Monotonic read consistency)单调读一致性是指如果一个节点从系统中读取出一个数据项的某个值后,那么系统对于该节点后续的任何数据访问都不应该返回更旧的值。
单调写一致性(Monotonic write consistency)指一个系统要能够保证来自同一个节点的写操作被顺序的执行。

分布式事务的解决方案

2PC(二阶段提交)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fa15893823644f318b209312220d1bbf.png在这里插入图片描述

2PC 引入一个事务协调者的角色来协调管理各参与者(也可称之为各本地资源)的提交和回滚,二阶段分别指的是准备(投票)和提交两个阶段。


准备阶段:事务管理器告诉资源管理器准备执行事务,并锁住需要的资源。当准备完成后,资源管理器向事务管理器报告已准备就绪。


提交阶段:如果所有资源管理器都准备成功,第二阶段事务管理器回要求所有的资源管理器执行提交操作。如果任一资源管理器在第一阶段返回准备失败,那么事务管理器回要求所有的资源管理器在第二阶段执行回滚操作。


二阶段看起来能提供原子性操作,但是不幸的是,二阶段提交还是有几个缺点的
1.2PC是一个同步阻塞协议,资源管理器在执行的过程中会锁定资源。其他第三方节点想访问这些资源的时候不得不处于阻塞状态
2.一阶段有超时机制,在第一阶段事务管理器没有收到资源管理的响应,或者资源管理器挂了。超时就会判端事务失效,向所有资源管理器发送回滚命令。但二阶段只能不断重试
3.事务管理器存在单点风险,如果发生故障,则资源管理器会一直阻塞下去。

XA规范

XA规范是X/Open 组织针对二阶段提交协议的实现做的规范。目前几乎所有的主流数据库都对XA规范提供了支持
XA规范的特点是:
1.对代码无侵入,开发比较快速
2.对资源进行了长时间的锁定,并发程度比较低
在这里插入图片描述


TCC
在这里插入图片描述

TCC这种方案应该是在企业中应用最广泛的一种方案,在业务层面实现分布式事务。TCC是Try、Confirm、Cancel三个词语的缩写。


Try:负责业务资源检查和预留


Confirm:二阶段提交操作,所有的Try都成功了,则执行Confirm操作。Confirm真正执行业务,使用Try预留的资源


Cancel:二阶段回滚操作,只有一个Try失败了,则走到Cancel操作。Cancel释放Try预留的资源


特点:
1.并发程度高,在业务层面锁定资源
2.开发量大,一个业务员需要提供Try/Confirm/Cancel三个方法


本地消息表(异步确保)
在这里插入图片描述

我们以买书为例说一下大致流程
1.账号服务扣减账户余额,同时写入一条消息(状态为进行中),注意扣减账户余额和写消息在一个本地事务中
2.账号服务轮询消息表,将进行中的消息发送到消息队列
3.仓库服务收到消息后,扣减相应的库存。扣减完成后将结果通过给账号服务,账号服务将消息的状态更新为已完成(或者删除)
4.当消息发送失败,或者消息消费失败时,会不断重试,因此仓库服务要保证消费的幂等性。
特点 :需要创建额外的消息表,不断对消息表轮询


RocketMQ事务消息
在这里插入图片描述

在本地消息表方案中,生产者需要额外创建本地消息表,还要对本地消息进行轮询。RocketMQ在4.3之后的版本正式支持事务消息,该事务消息的本质是把本地消息表放在RocketMQ上,解决生产端消息发送和本地事务执行的原子性问题


RocketMQ实现分布式事务的流程如下:
1.producer向mq server发送一个半消息
2.mq server将消息持久化成功后,向发送方确认消息已经发送成功,此时消息并不会被consumer消费
3.producer开始执行本地事务逻辑
4.producer根据本地事务执行结果向mq server发送二次确认,mq收到commit状态,将消息标记为可投递,consumer会消费该消息。mq收到rollback则删除半消息,consumer将不会消费该消息,如果收到unknow状态,mq会对消息发起回查
5.在断网或者应用重启等特殊情况下,步骤4提交的2次确认有可能没有到达mq server,经过固定时间后mq会对该消息发起回查
6.producer收到回查后,需要检查本地事务的执行状态
7.producer根据本地事务的最终状态,再次提交二次确认,mq仍按照步骤4对半消息进行操作


消息投递到mq server,consumer消费失败怎么办?
如果是消费超时,重试即可。如果是由于代码等原因真的消费失败了,此时就得人工介入,重新手动发送消息,达到最终一致性。


最大努力通知

最大努力通知这种方案在充值系统中经常被使用
充值系统通过不断的重试将充值结果推送给账户系统。因此账户系统接收充值结果的系统要保持幂等。另外充值充值系统还要提供回查接口,让账户系统主动校验充值的状态。
在这里插入图片描述


Seata AT模式

这是阿里开源的事务框架Seata中主推的事务模式。Seata AT是一种无侵入的事务解决方案。事务的一阶段和二阶段均由框架自动生成。用户SQL作为分布式事务的一阶段,而二阶段由框架自动生成提交/回滚操作。和XA模式很类似
Seata AT模式特点:
1.对代码无侵入,开发速度较快
2.需要用全局锁来保证隔离性,并发程度较低

文章来源:https://blog.csdn.net/weixin_52352342/article/details/135741394
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。