03.分布式事务解决方案

一、分布式事务介绍


1.1分布式事务介绍
分布式事务介绍
1588519934497
1.2 Base理论

CAP理论,C:一致性,A:可用性,P:分区容错性。分布式环境下,三者取其二。

  • Eureka:AP,保证了可用性,舍弃了一致性。

  • Zookeeper:CP,每一个节点必须能够找到Master才能对外提供服务,舍弃了可用性。

Base理论,BA:基本可用,S:中间状态,E:最终一致性。

  • 基于CAP理论演化而来的,是对CAP定理中一致性和可用性的一个权衡结果。

  • 核心思想:我们无法做到强一致性,但是每一个应用都可以根据自身的业务特点,采用一些适当的方式来权衡,最终达到一致性。

  • BA:分布式系统中因为一个原因,导致出现了一些问题,允许损失掉部分服务的可用性,保证我核心功能的高可用。

  • S:允许系统之间存在一个中间状态,并不会影响正常的去使用整个系统,允许数据的同步存在延迟。

  • E:系统中所有的数据副本经过一定时间后,最终能够达到一致的状态,不需要保证系统数据强一致性。

二、分布式事务解决方案【重点


2.1 2PC两段提交

两段提交分为两个阶段:

  • 第一个阶段是准备阶段,参与者需要开启事务,执行SQL,保证数据库中已经存在相应的数据。参与者会向TransactionManager准备OK。

  • 第二个阶段当TransactionManager收到了所有的参与者的通知之后,向所有的参与者发送Commit请求。

问题1:执行的性能是很低的。一般是传统事务的10倍以上。

问题2:TransactionManager是没有超时时间的。

问题3:TransactionManager存在单点故障的问题

2PC两段提交
1588588652092
2.2 3PC三段提交

三段提交在二段提交的基础上,引入了超时时间机制,并且在二段提交的基础上,又多了一个步骤,在提交事务之前,再询问一下,数据库的日志信息,是否已经完善。

3PC三段提交
1588593392317
2.3 TCC机制

TCC(Try,Confirm,Cancel),和你的业务代码切合在一起。

  • Try:尝试去预执行具体业务代码。 下单订ing。。。

  • try成功了:Confirm:再次执行Confirm的代码。

  • try失败了:Cancel:再次执行Cancel的代码。

TCC
1588595818335
2.4 MQ分布式事务

RabbitMQ在发送消息时,confirm机制,可以保证消息发送到MQ服务中,消费者有手动ack机制,保证消费到MQ中的消息。

MQ分布式事务
1588597788593
2.5 LCN实现分布式事务

基于三段提交和TCC实现的

创建一个协调者工程,创建两个服务

协调者:添加依赖

<dependency>
    <groupId>com.codingapi.txlcn</groupId>
    <artifactId>txlcn-tm</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

协调者:编写配置文件 注意:需要添加一个空的application.properties文件

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///lcn?serverTimezone=UTC
    username: root
    password: root
  redis:
    host: 192.168.199.109
    port: 6379
    # 协调的端口号
tx-lcn:
  manager:
    port: 8070

协调者:添加注解

@EnableTransactionManagerServer

协调者:准备表

# 创建表
CREATE TABLE `t_tx_exception`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `group_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `unit_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `mod_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `transaction_state` tinyint(4) NULL DEFAULT NULL,
  `registrar` tinyint(4) NULL DEFAULT NULL,
  `remark` varchar(4096) NULL DEFAULT  NULL,
  `ex_state` tinyint(4) NULL DEFAULT NULL COMMENT '0 未解决 1已解决',
  `create_time` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

服务: 添加依赖

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.2</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
    <groupId>com.codingapi.txlcn</groupId>
    <artifactId>txlcn-tc</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>com.codingapi.txlcn</groupId>
    <artifactId>txlcn-txmsg-netty</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

服务: 编写配置文件

server:
  port: 8081

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///lcn?serverTimezone=UTC
    username: root
    password: root

tx-lcn:
  client:
    manager-address: localhost:8070

服务: 启动类添加注解

@EnableDistributedTransaction

服务:Service层添加注解

@Override
@Transactional
@LcnTransaction
public void createOrder() {
//        1. 减库存
    restTemplate.getForObject("http://localhost:8082/item",String.class);
    int i = 1/0;
//        2. 创建订单
    orderMapper.save();
}

测试,异常后,事务回滚

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值