什么是分布式事务:
简单来说 ,你多个项目 只要其中有一个没成功 那么即便是其他都成功了也要打回去 一个管一群
seata是什么
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。 Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案
什么是幂等
简单来说就是:一次发送请求的结果和多次发送的请求的结果一致
如何保证幂等性
可以考虑前校验或者后校验
前:提交按钮点击置灰,或者增加loading
添加唯一索引
什么是回表
简单来说就是添加了高级索引 可以通过这个索引直接找到,所以就不需要回表
聚集索引和非聚集索引
B+树上会存储这一行的全部数据,但是非聚集索引只会存储该列对应的值和相应行的主键。
分布式事务四种模式:
AT、TCC、Saga、XA
TC (Transaction Coordinator) - 事务协调者----seata
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器----总调用者
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
AT无业务入侵模式
AT模式的执行过程:1. TM发起全局事务,向TC注册全局事务信息。2. TC生成一个全局唯一的事务ID,并将该事务ID发送给TM。3. TM将事务ID发送给参与方的RM,参与方的RM根据该事务ID开启本地事务。4.在操作执行完成后,将操作的结果和事务ID通过RM报告给TC。5. TC收集到所有的操作结果,如果所有参与方都操作成功,则向所有的RM发送提交指令,本地事务提交;否则,向所有的RM发送回滚指令,本地事务回滚。6. 参与方的RM根据指令执行相应的操作,提交或回滚本地事务。7. 参与方的RM向TC报告最终的执行结果。8. TM接收到参与方的最终执行结果后,完成全局事务的最终提交或回滚。
更多时候 我们会选择 ap
CAP回顾
c=一致性 a=可用性 p=分区
什么是分区?
我们只能在C、A、P中选择两个条件。而对于业务系统而言,我们往往选择牺牲一致性来换取系统的可用性和分区容错性。
C:一致性
强一致性:
系统中的某个数据被成功更新后,后续任何对该数据的读取操作都将得到更新后的值
弱一致性
系统中的某个数据被更新后,后续对该数据的读取操作可能得到更新后的值,也可能是更改前的值。
最终一致性
是弱一致性的特殊形式,存储系统保证在没有新的更新的条件下,最终所有的访问都是最后更新的值
jdk回收强软弱虚
强引用:简单来说就是 就算内测不足 垃圾回收机制也不会回收
软引用:属于弱引用中最强的引用,它会在内存中停留一段时间 垃圾回收机制会根据jvm使用情况来决定是否回收
弱引用:只要弱引用的所指对象进行系统垃圾回收 不管内存情况如何 都会进行回收
虚引用:
虚引用无法通过get()来取到目标对象从而使用目标对象 观察源码可以发现get被重写永远是返回null
博客:软引用、弱引用和虚引用处理_kotlin 弱引用-优快云博客
【学习JVM】强引用,弱引用,软引用,虚引用_弱引用 强引用-优快云博客
分布式事务调用写法(本地事务)
acc表(第一步)
首先写一个mapper接口,里面写上两个方法 一个扣钱一个加钱
写上sql 微服务项目最好自己写sql 写方法 因为系统的有时候会用不了
service层也要写上接口
然后impl去继承 ,需要业务逻辑进行判断 而不是无脑继承
注意要开启本地事务,防止程序出错 造成 我转了钱 但是对方没收到 如果开了本地事务
那么就可以进行回滚
然后写controller层
接着就是订单表(第二步)
订单表所需的导包和yaml不多(目前来说)
yaml:
同样的写一个mapper接口
是新增方法 因为当你的acc表的数额进行变化的时候,那么你的订单表也会有记录,什么时候,转了多少钱等
同样也要上云
service层
impl继承
因为时间比较难搞 所有在impl层把它转好 并且生成订单编号
最后就是controller层了
时间绑定器:防止绑不上 所有impl层写一个 controller写一个 万无一失
第三步:远程调用(user——>acc)
配置feigb
AccountFeign: 去调用acc的controller
RecordFeign: 订单的controller
然后就是controller 调用两个服务的feign 在调用他们写好的方法(transfer=转账)(addTransactionRecord=订单记录)
注意:上面的user其实是写在seata里面 但是写在user里面可以进行biz模式
最后 biz模式
建立一个工程
导包
配置yaml 他就是作为一个tm 主要是调用 所以无需很多配置
dev
作为biz模式 简单来说 就是远程调用加远程调用:什么意思:就是seata去调user---user去调acc 再调 订单表
所以它的feign有三个(具体多少个看业务需求)
acc
订单
user
其实就是把他们各自的controller里面的方法头和参数复制一下
seata启动类 要挂上支持远程调用和注册nacos注解
然后就是他的controller类了
上面那个是跟user一个意思,就是直接调用acc和订单(这种就是在user里面不要写 把user复制一份到seata)
下面这个是 远程调用远程 也就是biz模式
开启分布式事务
进入seata容器
找到resources
找到file.conf文件
通过vi file.conf进去修改 store下面
service {
#vgroup->rgroup 服务分组 集群分组默认为"default"
vgroupMapping.my_test_tx_group = "default"
#only support single node 不改就是本地ip
default.grouplist = "192.168. 116.132:8091"
#degrade current not support 服务降级达到多次错误不走seata 不支持熔断,必须回滚
enableDegrade = false
#disable
disable = false
#unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
max.commit.retry.timeout = "-1"
max.rollback.retry.timeout = "-1"
}
退出容器
最后重启容器
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
放开网关的yaml
再放开acc里面yaml配置过的esata
定义好名字 拉到组里面 其他几个也一样 需要那几个就拉那几个
再给分布式事务的那个服务
开启 这个注解
报错信息
yaml问题
这种意思是 扫描不到路径 解决方法:看看你的serviceimpl有没有加@service注解(在你加了@MapperScan("com.cn.record.mapper")这句话的情况下)
这个错误意味着你有个yaml没上云
连接不上服务
要注意你的yaml里面的所有端口号是否一致
表示你在搞分布式事务的时候 feign这个包里面有个类没有加上这个注解
它的意思找不到feign需要的东西
看看有没有多导包
如果参数map 那么sql里面一定要有map类型