谷粒商城高级篇—分布式事务
分布式事务
本地事务:在分布式系统只能控制住自己的回滚,控制不了其他服务的回滚
分布式事务:最大原因——网络问题
本地事务
1、事务基本性质
- 原子性 Atomicity 同成功、同失败
- 一致性 Consistency 整体一致
- 隔离性 Isolation 事务之间相互隔离
- 持久性 Durablility 事务成功,数据一定入库
2、事务的隔离级别
- READ UNCOMMITTED 读未提交,脏读
- READ COMMITTED 读已提交,不可重复读
- REPEATABLE_READ 可重复读 mysql默认,幻读,mysql的InnoDB通过next-key locks机制避免幻读
- SERIALIZABLE 序列号
3、事务的传播行为
- PROPAGATION_REQUIRE,存在就加入,没有就创建
- PROPAGATION_SUPPORTS,存在就加入,没有就非事务
- PROPAGATION_MANDATORY,存在就加入,不存在抛异常
- PROPAGATION_REQUIRE_NEW,创建新事务
- PROPAGATION_NOT_SUPPORT,存在就挂起,没有就非事务
- PROPAGATION_NEVER,存在就抛异常,没有就非事务
- PROPAGATION_NESTED,存在就嵌套,没有就创建
4、SpringBoot 事务
@Transactional //注意:事务使用代理对象控制的,同一个对象内事务方法默认失效,原因是绕过了代理对象
解决:使用代理对象来调用事务方法
1、引入aop依赖,引入了aspectj
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> <version></version> </dependency>
2、@EnableAspectJAutoProxy(exposeProxy = true);开启 aspectj动态代理功能,以后所有动态代理都是aspectj创建的(没有接口也可以创建动态代理)。
3、用代理对象互调
@Transaction(timeout = 30) public void a(){ OrderServiceImpl orderService = (OrderServiceImpl) AopContext.currentProxy(); orderService.b(); orderService.c(); int i = 10/2; } @Transaction(propagation = Propagation.REQUIRED,timeout = 2) public void b(){ } @Transaction(propagation = Propagation.REQUIRED_NEW,timeout = 20) public void c(){ }
分布式事务
1、为什么有分布式事务
分布式系统:机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠TCP、存储数据丢失...
2、CAP定理与BASE理论
-
CAP定理
- 一致性Consistency
- 可用性Availability
- 分区容错性Partition tolerance
永远满足分区容错,一致性和可用性二选一
分布式系统中一致性算法:raft(领导选举、日志复制)、paxos
-
面列的问题
保证P和A,舍弃C
-
BASE理论
无法做到强一致性,保证最终一致性
- 基本可用 Basically Abailable
- 软状态 Soft State
- 最终一致性 Eventual Consistency
3、分布式事务集中解决方案
-
2PC模式
二阶提交:
第一阶段:事务协调器要求每个设计事务的数据库预提交此操作,并反应是否可以提交
第二阶段:事务协调器要求每个数据库提交数据
其中,任何一个否决,所有数据库回滚事务中的信息。
协议简单,商业数据库成本低
性能不理想,无法满足高并发
-
柔性事务-TCC事务补偿型方案
-
柔性事务-最大努力通知
按规律进行通知,不保证一定通知成功,但会提供可查询操作接口进行核对。
用在与第三方系统通信时。
结合MQ实现。
-
柔性事务-可靠消息+最终一致性方案(异步确保型)
业务事务提交之前,向实时消息服务请求发送消息,试试消息服务只纪律消息,不真正发送,事务提交后,确认发送。
Seata
开源分布式事务解决方案,提供AT、TCC、SAGA、XA事务模式
TC 事务协调者
TM 事务管理器
RM 资源管理器
AT模式,需要建立UNDO_LOG表,用与回滚
-
每个服务建立UNDO_LOG表
-
安装TC: seata-server
-
整合
-
导入依赖
<!--在common里导入seata--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> </dependency> -
启动seata服务器 seata-server(修改配置文件 conf/registry.conf文件)
-
所有用到分布式事务的微服务使用 seata DatasourceProxy代理自己的数据源
-
每个微服务导入 registry.conf file.conf
-
启动测试
-
给分布式大事务的入口标注 @GlobalTransactional
-
每个远程调用的小事务用@Transactional
默认 AT 模式,二阶段(第一阶段提交,二阶段可通过日志反向补偿进行回滚)
seata不适合高并发,适合不用高并发场景事务方法。
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~