一、分布式事务
分布式事务产生?
原因:主要是受分布式架构的影响,分布式架构中要确保多个数据源的数据一致性。
数据库的事务:
事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败。
什么是分布式事务:
分布式系统中,多个服务操作多个数据库,不同服务参与同一个操作时,要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。
分布式事务场景:
(分布式事务的数据体现)
单个服务多个数据源
多个服务多个数据源
分布式事务要解决的问题:
分布式理论:
1.CAP定理
—一致性(C):给请求,先等待,同步完,在相应
—可用性(A):给请求就给相应,即使数据没有同步(数据可能会出错或得到的不是最新数据)
—分区容错(P):服务与服务之间进行网络连接,若网络出现问题,一个服务进行更改后,另一个服务没有同步,出现了数据错误,当问题解决后,数据正常(恒成立)
这三者如何做组合:两两结合
CP:强一致
CA:不需要网络,单一服务
AP:强调可用性
3
2.BASE理论(柔性事务)
- 软状态:允许系统中存在中间状态,这个状态不影响系统可用性,如订单的”支付中”状态、不同节点数据副本同步延迟等。
举例:你参加工作后,通常在拿到第一个月工资的时候,都会选择向家里汇款,当你完成转账操作后,结果银行提示“您的转账预计3日内到账”,而该笔交易的状态为”转账中“。
- 最终一致:最终一致是指经过一段时间后,所有节点数据都将会达到一致。如订单的”支付中”状态,早晚会变为“支付成功”或者”支付失败”,使订单状态与实际交易结果达成一致,但需要一定时间的延迟、等待。
举例:向家里汇款2天后,家里人收到转载的钱。
- 基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。如,电商网站交易付款出现问题了,商品依然可以正常浏览。
举例:在这个期间,两个银行的通信网络出现问题,导致实际的转账操作无法完成,但你依然能查询到你的该笔交易状态为”转账中“。
分布式事务的解决方案:
—两阶段提交(2PC是基于XA规范分布式事务解决方案)
优点:强一致
缺点: 效率低,性能差(同步阻塞:牺牲性能保证数据同步)。
单点故障(第一阶段,rm出现异常,事务协调器死等)
数据不一致(提交事务时,事务协调器死了,没有通知到RM,RM死等)
第一阶段:事务执行但不提交(准备阶段)
事务协调者通知RM准备就绪等待(RM资源管理器)
第二阶段:事务提交阶段(事务提交阶段)
事务协调器向RM提交
异常情况:第一阶段事务协调器通知RM失败,第二阶段,准备就绪的进行回滚
—三阶段提交(是两阶段提交的升级版,主要解决的是单点故障,减少阻塞,但并没有解决)
(在两阶段提交之前添加一个阶段(询问阶段):事务协调器询问RM死没死,在进行后面阶段)
第一阶段:询问阶段
第二阶段:事务执行但不提交阶段
第三阶段:事务提交阶段
—TCC事务补偿
try:对数据进行预留
confirm:成功则删除预留数据
cancel:若失败,回滚
优点:效率好,性能好,无阻塞,不依赖关系型数据库(AP)
缺点:需要写大量的业务逻辑,且需要考虑很多复杂情况,防止出现业务悬挂和业务回滚,且2、3、4也会导致数据不一致
—可靠消息最终一致
核心:将分布事务拆分成多个本地事务进行处理(消息表)
正常生产消费
生产方异常
消息异常直接回滚
消费方异常
消息没有被消费,则让生产方重试,mq重试一定次数后,消费方一直失败,断开mq,为避免性能消耗,违背消费的消息如何处理?在生产方弄一个定时器,定时查询未成功的消息,然后进行发送,如果多次不不成功,要么消息本身有问题需要人工介入。
优点:消息时效性比较好
实现了消息可靠性
方案比较轻量,容易实现
缺点:、
场景化业务耦合性强
数据同步占用业务系统资源(消息表)
业务系统在使用关系型数据情况下,消息性能会受到关系型数据库的限制

二、课程发布
整体业务流程

第一个业务:上流数据 生产方
产生coursepub数据,修改课程状态
第二个业务:消费方
生成课程详情页html
将页面放在cdn上
业务分析
1.消息发送方业务实现
- 首先由前端点击按钮进行课程发布
- controller层调用server层,里面有两个方法分工不同,一个是操作数据库另一个是修改数据库状态,操作数据库有两张表,业务表和消息表。
- 当业务表和消息表操作完毕后发现消息给RabbitMQ。
- 为了确保消息是发送成功的,设置消息应答机制,无论成功与否都会发送给confirm callback
- 如果confirm callback接收到的是ACK表示交换机执行成功,调用数据库修改状态数据,将信息表中的状态改成已发送成功和课程基础表中的审核状态改成已发布。如果confirm callback接收到的是NACK表示交换机出问题了,需要打印日志人工处理
- 交换机执行结束后会把消息给队列,如果成功则不返回消息,如果失败则一定要返回给return callback,记录错误信息人工介入处理
- 如果confirm callback接收到的是NACK,交换机出故障,修改以后可以使用定时任务,循环扫描消息表中发送状态为未发送成功的,查询到后继续发送。
- 以上业务两大特别:消息的可靠性,分布式事务
实现步骤
1.导入mq依赖
2.配置mq公共配置
3.开启应答机制 properties
4,指定交换机和队列的名称—-nacos中服务管理中
5。在内容管理下配置mq持久化
6.内容管理下构建一个消息表
7.生成基础代码
代码实现
1.controller接口传入主要数据:课程id,机构id

(没有返回数据,怎么看发布是否成功—————-直接看审核状态:课程已发布)
2.业务
—判断关键数据
—判断业务数据:课程信息,课程计划,教师信息,课程分类
—保存消息数据
—给mq发送消息:消息唯一性,指定confirmcallback
—-confirmcallback中返回ack后,业务层修改消息数据状态
定时器:spring-task:
开启定时功能:EnableScheduling
定义一个方法,在方法上添加@Scheduled(cron=”0/10**?“)
2.消息消费方业务实现
