分布式事务介绍
分布式事务介绍:
1.什么是事务?
数据库事务(简称:事务,Transaction)是指数据库执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。如转账业务:一方扣款,一方增加金额。
2.事务的四个特性?
1.原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
2.一致性(Consistency):指的是操作前后,总数据保持保持不变。(-100块与+100块)
3.隔离性(Isolation)**:多个事务并发执行时,一个事务的执行不应影响其他事务的执行。张三取钱不会影响李四取钱。
4.持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。在事务结束时,此操作将不可逆转。
3.什么是分布式事务?
简单讲,在分布式系统中进行的事务就是分布式事务。意思就是说,在分布式系统中,也要保证事务的四个特性。
4.分布式事务的模型;
单个服务,多个数据库,是分布式事务;
多个应用,多个数据库也是分布式事务;
多个应用,调用其他的应用,再加上多个数据库也是分布式事务(微服务中的典型模型);
5.CAP理论?
CAP 定理,又被叫作布鲁尔定理。
C(Consistency):一致性:
对于数据分布在不同节点上的数据来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,
那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。
A(Availability):可用性:
非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。
P(Partition tolerance):分区容错性:
当出现网络分区后,系统能够继续工作。打个比方,这里集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。
CAP理论认为,这三个条件只能同时满足其中两个,不能同时满足三个;
网络无法 100% 可靠,分区其实是一个必然现象。
如果我们选择了 CA 而放弃了 P,那么当发生分区现象时,为了保证一致性,这个时候必须拒绝请求,但是 A 又不允许,所以分布式系统理论上
不可能选择 CA 架构,只能选择 CP 或者 AP 架构。
所以一般认为P是永远存在的,必须满足;
BASE理论:基于CAP理论,BASE理论认为系统基本可用,数据最终保持就可以了(允许数据可以短暂不一致)。
6.分布式事务的解决方案:
1.基于XA协议的两阶段提交:
假设数据库1控制库存,数据库2控制积分,数据库3控制日志;TransactionManagement为统一事务管理器
第一个阶段:
数据库1执行库存扣减操作,但是不提交----->汇报操作成功与否给TransactionManagement
数据库2执行积分增加操作,但是不提交----->汇报操作成功与否给TransactionManagement
数据库3执行记录日志操作,但是不提交----->汇报操作成功与否给TransactionManagement
第二个阶段:
TransactionManagement确认以上三个操作都成功了,然后通知三个数据库进行提交操作;
若是以上三个操作有一个失败了,则进行回滚操作;
优点:尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。
缺点:牺牲了可用性,对性能影响较大,不适合高并发高性能场景,如果分布式系统跨接口调用,目前 .NET 界还没有实现方案。
2.补偿事务(TCC)
TCC 将事务提交分为 Try(method1) - Confirm(method2) - Cancel(method3) 3个操作。
其和两阶段提交有点类似,Try为第一阶段,Confirm - Cancel为第二阶段,是一种应用层面侵入业务的两阶段提交。
Try:在这个阶段,先对数据进行备份,然后执行业务,提交事务,通知事务管理器操作成功与否;
Confirm:在这个阶段,事务管理器确认对各个数据库的操作是否有异常,无异常则confirm并更改干掉备份数据,有异常则进入cancel
Cancel:若有数据库操作失败,则执行代码,将原先的备份数据还原;
优点: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些
缺点:缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,
所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
7.分布式事务的实现技术:Seata
1.Seata介绍:
Seata是阿里巴巴开源的一款分布式事务解决方案,它具有以下优点:
对业务无侵入:不必要写很多的补偿事务的代码;
高性能:减少分布式事务解决方案所带来的性能消耗
Seata有两种模式:
1.AT模式:自动模式,不需要写很多自定义的业务代码,推荐使用这种模式;
2.TCc模式:手动模式,需要自定义业务代码;
Seata工作原理:
第1阶段:
通过代理数据源,逆向解析SQL,保留执行操作之前的数据和操作之后的数据,放到日志记录中,执行commit操作
第2阶段:
事务管理器收到了所有的分支事务状态汇报,
发现没有问题,全局提交决定。协调器就异步通知所有相关的分支事务进行删除日志文件。
发现如果有问题,就进行全局回滚。异步通知所有相关的分支事务找到日志记录,将数据进行回滚。
2.Seata的使用:
0.在每一个分布式事务涉及到数据库中添加undolog表:
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
1.在各个微服务中加入Seata的起步依赖;
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</dependency>
2.配置代理数据源:
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
@Primary//主要标识.
@Bean("dataSourceProxy")//代理数据源
public DataSourceProxy dataSourceProxy(DataSource dataSource) {
return new DataSourceProxy(dataSource);
}
@Bean("jdbcTemplate")
@ConditionalOnBean(DataSourceProxy.class)//spring容器中如果有该bean就进行注入
public JdbcTemplate jdbcTemplate(DataSourceProxy dataSourceProxy) {
return new JdbcTemplate(dataSourceProxy);
}
3.配置客户端连接到TC的服务器的地址的配置
file.conf
regestry.conf
application.properties
https://seata.io/zh-cn/docs/user/configurations.html
4.开启TC服务器
TC就是一个服务器 seata-server ,解压启动bin下的bat脚本就可以了
5.在最开始的全局事务中添加一个注解,用于开启全局事务
@GlobalTransactional
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?