分布式事务笔记 百度云链接:https://pan.baidu.com/s/1S8vpsgsqFLQj6xRNUqyIIg 提取码:1111
本地笔记:file:///E:/%E6%A1%8C%E9%9D%A2/%E8%B0%B7%E7%B2%92%E5%95%86%E5%9F%8E/%E8%B0%B7%E7%B2%92%E5%95%86%E5%9F%8E/%E9%AB%98%E7%BA%A7%E7%AF%87/%E8%AF%BE%E4%BB%B6/03%E3%80%81%E6%9C%AC%E5%9C%B0%E4%BA%8B%E5%8A%A1&%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1.pdf
分布式事务-订单服务
1.问题:本地服务失败,本地事务回滚;但是,远程服务无法回滚
1.1.问题描述
1.1.1.订单服务失败,订单进行回滚。但是远程锁定库存服务,则无法回滚。或者其他远程无法回滚
1.1.2.原理:本地事务,在分布式系统,只能控制自己回滚,控制不了其他服务。
1.1.3.原因:网络问题+分布式机器。
1.2.解决方法:分布式事务
1.2.1.分布式最大原因:网络问题+分布式机器
出现的原因:结点之间节点之间互相的状态不能同步,包括网络状态问题,这些数据,互相感知不到。希望有人来协调这件事情
1.2.1.分布式事务原理:分布式事务
2.分布式事务
分布式事务笔记 百度云链接:https://pan.baidu.com/s/1S8vpsgsqFLQj6xRNUqyIIg 提取码:1111
2.1 本地事务
2.1.1.事务的基本性质
原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)、持久性(Durabilily),简称就是 ACID
原子性:一系列的操作整体不可拆分,要么同时成功,要么同时失败
一致性:数据在事务的前后,业务整体一致。
转账。A:1000;B:1000; 转 200 事务成功; A:800 B:1200
隔离性:事务之间互相隔离。 持久性:一旦事务成功,数据一定会落盘在数据库。
2.1.2 事务的隔离级别
READ UNCOMMITTED(读未提交) 该隔离级别的事务会读到其它未提交事务的数据,此现象也称之为脏读。
READ COMMITTED(读提交) 一个事务可以读取另一个已提交的事务,多次读取会造成不一样的结果,此现象称为不可重 复读问题,Oracle 和 SQL Server 的默认隔离级别。
REPEATABLE READ(可重复读) 该隔离级别是 MySQL 默认的隔离级别,在同一个事务里,select 的结果是事务开始时时间 点的状态,因此,同样的 select 操作读到的结果会是一致的,但是,会有幻读现象。MySQL 的 InnoDB 引擎可以通过 next-key locks 机制(参考下文"行锁的算法"一节)来避免幻读。
SERIALIZABLE(序列化) 在该隔离级别下事务都是串行顺序执行的,MySQL数据库的 InnoDB 引擎会给读操作隐式 加一把读共享锁,从而避免了脏读、不可重读复读和幻读问题。
2.1.3 事务的传播行为
1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,
就加入该事务,该设置是最常用的设置。
2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当
前不存在事务,就以非事务执行。
3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果
当前不存在事务,就抛出异常。
4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当
前事务挂起。
6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,
则执行与 PROPAGATION_REQUIRED 类似的操作
2.1.3 SpringBoot 事务关键点
1).事务的自动配置
TransactionAutoConfiguration
2).事务的坑
在同一个类里面,编写两个方法,内部调用的时候,会导致事务设置失效。原因是没有用到
代理对象的缘故。
解决:
0)、导入 spring-boot-starter-aop
1)、@EnableTransactionManagement(proxyTargetClass = true)
2)、@EnableAspectJAutoProxy(exposeProxy=true)
3)、AopContext.currentProxy() 调用方法
原因:事务是使用代理对象来控制的。同一对象内,事务方法互调,默认失效;原因绕过了代理对象
2.1).本地事务失效
代码例如
2.2 分布式事务
2.2.1 为什么有分布式事务
分布式系统经常出现的异常
机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠的 TCP、存储数据丢失。。。
分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个
东西,特别是在微服务架构中,几乎可以说是无法避免。
2.2.2 CAP 定理与 BASE 理论
1).CAP 定理
CAP 原则又称 CAP 定理,指的是在一个分布式系统中
一致性(Consistency):
在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(Availability)
在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容错性(Partition tolerance)
大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。
分区容错的意思是,区间通信可能失败。比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信。
CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
分布式系统中实现一致性的 raft 算法、paxos
http://thesecretlivesofdata.com/raft/
节点状态:候选人、领导、随从
关键词: 自旋、心跳、选举
2).面临的问题
对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,所
以节点故障、网络故障是常态,而且要保证服务可用性达到 99.99999%(N 个 9),即保证
P 和 A,舍弃 C。
3).BASE 理论
是对 CAP 理论的延伸,思想是即使无法做到强一致性(CAP 的一致性就是强一致性),但可
以采用适当的采取弱一致性,即最终一致性。
BASE 是指
基本可用(Basically Available)
软状态( Soft State)
最终一致性( Eventual Consistency)
4).强一致性、弱一致性、最终一致性
从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了
不同的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一
致性。如果能容忍后续的部分或者全部访问不到,则是弱一致性。如果经过一段时间后要求
能访问到更新后的数据,则是最终一致性
2.2.3 分布式事务几种方案
1).2PC 模式、3PC
2).柔性事务-TCC 事务补偿型方案
3).柔性事务-最大努力通知型方案
4).柔性事务-可靠消息 + 最终一致性方案(异步确保型)
实现:业务处理服务在业务事务提交之前,向实时消息服务请求发送消息,实时消息服务只
记录消息数据,而不是真正的发送。业务处理服务在业务事务提交之后,向实时消息服务确
认发送。只有在得到确认发送指令后,实时消息服务才会真正发送。
防止消息丢失:
/**
- 1、做好消息确认机制(pulisher,consumer【手动 ack】)
- 2、每一个发送的消息都在数据库做好记录。定期将失败的消息再次发送一
遍
*/
3. Seata
3.1 Seata 是什么?
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
3.2 快速开始
3.2.1 SEATA 的分布式交易解决方案
3.2.2 操作seata步骤
1).建立数据库-已经创建好
2).创建 UNDO_LOG 表 -每个数据库都加**
SEATA AT 模式需要 UNDO_LOG 表
– 注意此处0.3.0+ 增加唯一索引 ux_undo_log
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=1 DEFAULT CHARSET=utf8;
3).为示例业务创建表–已经建好
4).安装seata服务器、启动服务
4.1).安装seata服务器
安装seata事务协调器.zip
从 https://github.com/seata/seata/releases,下载服务器软件包,将其解压缩。
4.2).common中seata依赖
<!-- 分布式事务seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
4.4).修改seata配置文件 --registry.conf
设置配置中心为nacos,修改nacos地址
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa 指定注册中心
type = "nacos"
nacos {
serverAddr = "192.168.56.10:8848"
namespace = "public"
cluster = "default"
}
4.5).添加seata配置类 --把Seata作为数据库代理
a.order项目
order中
@Configuration
public class MySeataConfig {
@Autowired
DataSourceProperties dataSourceProperties;
@Bean
public DataSource dataSource(DataSourceProperties dataSourceProperties) {
HikariDataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
if (StringUtils.hasText(dataSourceProperties.getName())) {
dataSource.setPoolName(dataSourceProperties.getName());
}
return new DataSourceProxy(dataSource);
}
}
b.ware项目
4.6).把seata服务器的注册、file配置文件导入order、ware的resources下
4.7).修改order、ware的file.conf
vgroup_mapping.{application.name}-fescar-service-group = “default”
如:
vgroup_mapping.gulimall-order-fescar-service-group = “default”
vgroup_mapping.gulimall-ware-fescar-service-group = “default”
或者 配置文件配置
#spring.cloud.alibaba.seata.tx-service-group=sss
4.8).添加事务注解
a.分布式大事务的入口标注@GlobalTransactional
就是:order的OrderServiceImpl的submitOrder
b.每一个远程的小事务用@Trabsactional
就是:ware的WareSkuServiceImpl的orderLockStock
4.9).启动seata服务器
4.10).linux启动seata服务器
Usage: sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows) [options]
Options:
--host, -h
The host to bind.
Default: 0.0.0.0
--port, -p
The port to listen.
Default: 8091
--storeMode, -m
log store mode : file、db
Default: file
--help
e.g.
sh seata-server.sh -p 8091 -h 127.0.0.1 -m file
5).运行示例
启动 order
启动 ware
3.3 高并发下,分布式事务seata使用的问题
1).高并发下,不适合2PC、TCC,故不使用Seata的分布式事务
2).如下单服务,高并发下使用:可靠消息 + 最终一致性方案(异步确保型)
3).介绍–
高并发下,分布式事务不适合seata,@GlobalTransactional
高并发下,可使用:可靠消息 + 最终一致性方案(异步确保型)
为了保证高并发,远程服务自己回滚。
1、可以发消息给远程服务
2、远程服务自己也可以回滚(自动解锁模式),消息(延迟队列)