Closed AugustTuan closed 2 years ago
老师讲了什么?
老师这一集介绍了本地事务,事务的ACID特性,事务的传播行为。
事务的ACID特性
Atomicity——原子性,同一个事务的操作要么同时成功要么同时失败(下订单,锁库存)
Isolation——隔离性,不同事务之间互相不会影响。A事务回滚不会导致B事务回滚(自己写了异常机制另说)
Durabilily——持久性,一旦事务执行成功,就会落盘在数据库
Consistency——一致性,前面三个特性,一起保证了,业务在事务执行的前后,状态时符合预期的(不能扣了库存,但是没下订单)
老师再次强调了本地事务的场景(下订单,减库存,扣减积分,这三个是和同一个数据库建立的同一个连接里的三条sql语句,那他们是一个本地事务,他们才能同时回滚)
老师提到了本地事务在springBoot中的应用,@Transactional
注解
然后老师引入了一个事务中很重要的概念——事务的隔离级别(是数据库规定的规范,注解@Transactional(isolation=xxx)
)
读未提交,事务可以读到其他未提交事务的数据(但是人家回滚了,这个数据就是假数据,这就是脏读)
读已提交,事务只能读到其他事务已经提交的数据(Oracle和sqlSever的默认事务级别,但是同一个事务里面,中间有其他事务修改了数据,两次读到的数据可能会不一致,这就是不可重复读问题)
可重复读,整个事务期间内,多次读取的结果和第一读取的结果保持一致(mysql默认的隔离级别)。但是这里又会有一种特殊的不可重复读,即其他数据插入或者删除记录后,范围查询的记录数会不一致。
关于幻读,可重复读的真实用例是什么? - 小朋友的回答 - 知乎 https://www.zhihu.com/question/47007926/answer/253406510
串行化,事务之间直接排队操作,一个执行完再执行下一个,好了,什么问题都没有了,性能也没有了
之后老师引入了另外一个重要的概念——事务的传播行为,老师介绍了最常用的两种(传播行为就是被调用的事务要不要和父事务共用一个事务)
Propgration_Required——和调用事务共用一个事务,所有自己单独的事务设置失效和都和父事务保持一致
Progration_Requires_New——自己单独开一个新事务
老师专门举了一个例子(老师将传播行为比作要不要乘一个电梯)
@Transactional
public void a(){
b(); //a事务和b事务在同一个事务里面,会一起回滚
c();///c事务单独开一个事务,a不会影响c
}
@Transactional(propagation=Propagation.REQUIRED)
public void b(){
}
@Transactional(propagation=Propagation.REQUIRED_NEW)
public void c(){
}
之后老师提到了事务是通过代理对象控制的,同类调用问题的解决blabla的,没听懂
学习策略:
掌握程度
课程难度
时间花费
遗留问题
2:00 事务的隔离性是不是指同一个数据库的不同事务是不想不影响的?
8:55 老师在讲事务的传播行为的时候,弹幕说,直接调用同一个类的事务方法会导致事务失效,即使设置传播级别,因为aop的原因。 这里我不明白(他的意思是b和c不能跟a写在一个类里面)
12:20 老师说事务机制使用代理来实现的,在同一类里面调用,就不是代理对象了
15:50 有人说在全局异常的时候讲过动态代理,还有人说 spring2默认是cglib代理了
18:15 弹幕说不用整这么麻烦,直接注入就行了 还有说spring上下文中是可以获取到代理对象的
接口文档
老师讲了什么?
这一节课老师引入了CAP定理,并且分析了他们不可能同时成立的问题。 之后老师通过如何达成CP的问题,又引入了Raft算法。
老师开头又是讲了一遍,分布式系统下,由于网络问题,机器宕机,消息丢失,消息乱序,数据错误这些想要实现分布式事务必须正式和协调的问题
老师在讲分布式事务之前,老师先提到了CAP定理,这是分布式系统的原则
Consistency(一致性)——多台机器的所有数据备份必须在同一时刻有同样的值,要么给你返回一个错误,要么返回正确的值。
Availability(可用性)——任何客户端的请求都会得到响应,不会给你返回错误,强调不出错,但是数据不保新。
Partition tolerance(分区容错性)——分布式系统通过网络进行通信,当网络通信出现问题,系统仍然继续运行,不会挂掉。
这CAP三个定理,P是必定遵守的,应该网络不可能保证不出故障。而CA两个定理是不相容的,只能遵守其中一个
比如,如果同时具有分区容错性和可用性,AB之间网络通信出现了问题,考虑可用性B可以继续读取数据。但是如果要求一致性,那么整个集群就应该停止工作,否则在不同机器读取不同的数据。
想要满足AP定理,很简单,就是允许客户端读取同一个数据出现差异即可
但是想要保证所有机器的数据保证一致性,则需要引入一些算法,老师这里介绍的是Raft算法
raft算法的三个节点状态
两个超时时间
raft的核心机制
日志复制
客户端向领导节点发送请求,领导节点记录日志
领导节点在下一次心跳时间将请求日志发送给随从
当大多数节点同步日志并返回,领导节点提交数据库操作,响应客户端
领导节点在写一次心跳,继续将日志发送给随从,其他节点也跟着提交(如果有节点中间宕机了,重启的时候,接收最新的日志也会进行同步操作)
领导选举
当领导节点挂了以后,第一个自旋时间结束的节点成为候选节点,给自己投一票,并让其他随从给他投票,获得大多数票即可成为领导节点
如果有多个候选节点的票数一致,那么会重新进行一次自旋,再来一次投票,直到选出领导节点(自旋时间都是随机的)
网络分区下的raft算法保证一致性(节点进行了网络分区,并且分区间出现了通信故障)
学习策略:
掌握程度
课程难度
时间花费
课程收获
遗留问题
6:35 分布式系统,每个服务连的都是不同的数据库,难道每个服务都要备份同一个数据?备份在哪呢?
7:00 完了,我又忘记了节点代表什么了?网络地址? 指的是服务器本身?
这三个机器好像是一个服务吧,主从复制?
10:00 这里只保证部分可用不久满足可用性了吗?
22:30 候选者可以给候选者投票吗
候选人会第一时间给自己投票
29 :00 老师说大多数机器,那肯定还是有机器不一致啊
32:00 老师举得这个例子,如果上下都是两个节点呢?
网络通信什么过程,由什么组成的来着?
接口文档
老师讲了什么?
这一集老师引入了CAP理论的延申BASE理论
老师基于上一个可的raft算法,提出问题,该算法能够保证可用性?
答案是不能,比如有3台机器和另外三台机器分区通信失败,raft机制就会导致两边都不可用
那么老师又提到,在实际开发者,节点故障和网络故障是常态,相对于一致性,可用性才是最基本的,至少得让用户能够正常使用系统。所以真实开发都是选择AP,舍弃C
但是,对于订单系统,一致性又是必须保证,那该怎么办呢?老师因此提出了BASE理论(Bascically Available 基本可用)
基本可用的逻辑,就是在可用性和一致性之前寻找平衡。
当系统出现故障的时候,允许损失部分可用性:
对于一致性
一致性的不同策略
强一致——数据一旦被更新就可以立马被查询到
弱一致——客户端能够容忍部分时间,部分机器无法查询到更新的数据。
最终一致性——最终经过一段时间后,可以查询到更新的数据
学习策略:
掌握程度
课程难度
时间花费
课程收获
遗留问题
接口文档
老师讲了什么?
这一集老师介绍了几种分布式事务的实现方案
刚性事务-遵循ACID,强一致的方案
2PC模式(2 phase commit 二阶段提交)
遵循BASE理论,保证最终一致性的方案
柔性事务-TCC事务补偿方案
针对高并发系统,需要用到消息队列
柔性事务-最大努力通知方案
柔性事务-可靠消息-最终一致性方案
学习策略:
掌握程度
课程难度
时间花费
课程收获
遗留问题
接口文档
老师讲了什么?
这一集老师介绍阿里巴巴提供的一个分布式事务的框架,Seata的原理和环境准备。
Seata介绍——阿里巴巴研发的,一个开源、高性能的分布式事务解决方案。(为用户提供了多种事务模式)
SEATA的三个重要术语
TC——事务协调者,用户控制全局事务的提交和回滚(控制大事务和小事务)
TM——事务管理器,负责开启、提交、回滚总事务。(下单)
RM——资源管理,相当于各个微服务各自的本地事务,直接和各个服务的数据库进行交互。(保存订单,锁定库存,扣减积分)
SEATA的工作流程
下单的时候,TM告诉TC要开启一个全局事务
当下单服务调用锁定库存呢,扣减积分等微服务的时候,微服务会去TC进行注册RM,并且实时汇报事务的状态
当其中有一个小事务失败,TC感知到后,命令其他的RM也进行回滚
SEATA的环境搭建
创建各个业务的数据库
创建UNDO_LOG表,用于已经提交事务的反向补偿。原理是记录提交前的数据,撤销时魔改数据库(适用于AT,Auto Transaction 模式,事务执行成功会自动给提交,失败会自动撤销)
安装事务协调器TC:seata-server
学习策略:
掌握程度
课程难度
时间花费
课程收获
遗留问题
接口文档
老师讲了什么?
学习策略:
掌握程度
课程难度
时间花费
课程收获
遗留问题
接口文档
老师讲了什么?
这一集老师说明了Seata为什么不适合下订单,并且提出了适合高并发场景的解决方案——可靠消息+最终一致性方案
首先老师提到,我们之前用的Seata的AT模式,是前面提到的2phase Commit的一个演变模式:
一阶段,Seata自动就提交了
二阶段不是回滚而是通过回滚日志来进行反向补偿。
这个Seata模式并不适合高并发系统,而适用于一般的分布式场景,比如上架一个商品信息,需要远程调用各个服务,保存库存,商品,图片,规格参数等信息。这种情况没有高并发需求。
老师还大致看了一下Seata的原理,会用到各种锁机制,一加锁,高并发就变成串行化了,所以不适合高并发业务。
对于下单这种高并发系统,则需要使用消息队列来解决
订单服务回滚以后,可以发消息给库存服务,让其解锁
库存服务可以自动解锁
老师展示了锁库存的服务的完整逻辑
在锁库存的时候,保存库存工作单(xxx订单锁库存)和库存工作单详情(具体锁库存的商品id,数量等信息)
设置一个定时任务,检查下单业务是否成功,如果失败,库存服务根据库存工作单解锁库存
定时任务扫描数据库非常麻烦,老师又提出了延时队列来代替定时作业
库存锁成功以后,将消息发送给延时队列,经过一段时间给到库存解锁服务,库存解锁服务看到队列中的锁定消息,如果发现对应的订单下单失败,就进行解锁。
学习策略:
掌握程度
课程难度
时间花费
课程收获
遗留问题
接口文档
P283 商城业务-分布式事务-本地事务在分布式下的问题
老师讲了什么?
老师这一集通过远程锁库存的两个问题,引入了分布式事务
老师首先介绍了我们目前使用的本地事务+异常的机制
给订单服务下单和远程锁库存偶添加上@Transactional注解,当远程锁库存服务抛出异常后,本身会进行事务回滚,再抛异常,让下单感知到异常,也进行回滚。从而实现事务性。
但老师提出了本地事务+异常的问题
如果远程锁库存方法假失败,即库存锁定成功,但是超时没有返回,此时订单会回滚,但是库存已经扣减
远程锁库存方法执行成功,但是其他例如扣减积分的方法失败,创建订单会回滚,但无法让锁库存方法回滚
10:00 老师讲了 所谓本地事务,控制范围就是在同一个数据库的同一次连接里面,订单数据库的事务没有办法·控制库存数据库。想要在分布式系统下,控制不同服务的回滚,就需要使用分布式事务(产生分布式事务的原因就是因为网络超时问题,不知道远程事务失败的真假+分布式系统操作不同数据库)
学习策略:
掌握程度
课程难度
时间花费
遗留问题
接口文档