分布式事务-订单服务

分布式事务笔记 百度云链接: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

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、远程服务自己也可以回滚(自动解锁模式),消息(延迟队列)

4).高并发下,使用延迟队列,实现分布式事务。如下单服务

高并发下,使用延迟队列见

订单服务的分布式事务-延迟队列

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值