分布式事务:TX-LCN分布式事务框架整合实践

目录

1.前序

2.过程

   2.1 TX-LCN框架介绍 

   2.2 环境搭建

      2.2.1 开发环境

      2.2.2 数据库环境

      2.2.3 Tx-Manager下载和配置

      2.2.4 微服务启动

3.总结


1.前序

现如今,分布式框架纵横的大潮下,对于分布式的相关应用和技术的了解和使用也是必不可少的。最显著的几个技术点,我认为大概就是分布式事务,分布式锁,分布式高并发处理等等。而今天,我这边主要和大家分享一下,个人通过实践操作在分布式事务操作方面的过程。

2.过程

2.1 TX-LCN框架介绍

tx-lcn框架官网地址:http://www.txlcn.org/zh-cn/docs/preface.html

相关介绍,官网有详细信息。下面,我就其主要流程原理做下简要说明。

该框架的工作原理流程内容主要就是如图所示。个人简单总结一下:

TX-LCN框架中,为我们提供了一个核心中间件Tx-Manager,它是一个事务管理器。而我们的微服务或项目(会加入框架依赖包)作为Tx-Client端,在分布式服务调用过程中,从请求发起到结束,请求链路中,请求发起方或参与方与Tx-Manager的互动都由Tx-Client控制,所有的事务都交由此事务管理器Tx-Manager处理。如图工作流程:

①一个请求发起

②会先去Tx-Manager那里创建一个事务组

③再调用微服务A接口,调用的同时也会去申请加入步骤②中创建的事务组

④然后调用微服务B接口,也会申请加入事务组

⑤链路中可添加更多的微服务,每个服务调用都会加入事务组

⑥待请求结束后,会返回到请求发起方。再由请求发起方,通知Tx-Manager事务组。

⑦Tx-Manager开始对事务组中的每一个事务单元进行处理,并将处理结果记录。

⑧最后对每一个事务单元的处理结果进行整合,并决定整体事务是提交或是回滚,将最终结果返回给请求发起方。

2.2 环境搭建

2.2.1 开发环境

我本次的项目框架使用的是:SpringCloud版本Finchley.SR4,SpringBoot版本2.0.5.RELEASE,Redis

坑点:原本环境我是使用的稳定版本Dalston SR1和1.5.9.RELEASE,但是与TX-LCN框架整合后多次测试时启动报错。尝试更替依赖等,尝试很久无果,后考虑是环境低版本导致。所以后来切换到了高版本,果然就可以正常启动了。

2.2.2 数据库环境

  1. 创建MySQL数据库, 名称为: tx-manager
  2. 创建数据表,sql语句如下:
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;

此表是用来记录事务组处理事务单元的信息记录。

2.2.3 Tx-Manager下载和配置

我是直接使用的官网的SpringCloud Demo中的TM(Tx-Manager简称)。GitHub下载地址:https://github.com/codingapi/txlcn-demo ;可以只下载txlcn-demo-commontxlcn-demo-tm,其他的为Demo代码,也可以下载参考。

下载完成后,引入自己的IDEA工具。结构如下:

这里我需要说明一下,为什么我引入了txlcn-demo-common。其实可以不用引入,但这个是Demo中的通用依赖包,里面有一些共用依赖,我这边当时单独引入txlcn-demo-tm启动时有报错,应该是包依赖问题,没有自行添加依赖测试,有兴趣的可以自己添加依赖后单独启动试试。所以我这边就将两个子项目一起引入了,是可以正常启动的。

引入上面的项目后,需要修改两个地方:

①在启动类添加注解@EnableTransactionManagerServer

package org.txlcn.tm;

import com.codingapi.txlcn.tm.config.EnableTransactionManagerServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableTransactionManagerServer
public class TransactionManagerApplication {

    public static void main(String[] args) {
        SpringApplication.run(TransactionManagerApplication.class, args);
    }
}

②修改application.properties文件,配置如下:

##################
# 这个是启动本服务的配置文件,其它的application-xxx.properties 是开发者的个性化配置,不用关心。
# 你可以在 https://txlcn.org/zh-cn/docs/setting/manager.html 看到所有的个性化配置
#################

spring.application.name=TransactionManager
server.port=7970
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
# 数据库方言
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

# 第一次运行可以设置为: create, 为TM创建持久化数据库表
spring.jpa.hibernate.ddl-auto=validate

# TM监听IP. 默认为 127.0.0.1
tx-lcn.manager.host=127.0.0.1

# TM监听Socket端口. 默认为 ${server.port} - 100
tx-lcn.manager.port=8070

# 心跳检测时间(ms). 默认为 300000
tx-lcn.manager.heart-time=300000

# 分布式事务执行总时间(ms). 默认为36000
tx-lcn.manager.dtx-time=8000

# 参数延迟删除时间单位ms  默认为dtx-time值
tx-lcn.message.netty.attr-delay-time=${tx-lcn.manager.dtx-time}

# 事务处理并发等级. 默认为机器逻辑核心数5倍
tx-lcn.manager.concurrent-level=160

# TM后台登陆密码,默认值为codingapi
tx-lcn.manager.admin-key=codingapi

# 分布式事务锁超时时间 默认为-1,当-1时会用tx-lcn.manager.dtx-time的时间
tx-lcn.manager.dtx-lock-time=${tx-lcn.manager.dtx-time}

# 雪花算法的sequence位长度,默认为12位.
tx-lcn.manager.seq-len=12

# 异常回调开关。开启时请制定ex-url
tx-lcn.manager.ex-url-enabled=false

# 事务异常通知(任何http协议地址。未指定协议时,为TM提供内置功能接口)。默认是邮件通知
tx-lcn.manager.ex-url=/provider/email-to/



# 开启日志,默认为false
tx-lcn.logger.enabled=true
tx-lcn.logger.driver-class-name=${spring.datasource.driver-class-name}
tx-lcn.logger.jdbc-url=${spring.datasource.url}
tx-lcn.logger.username=${spring.datasource.username}
tx-lcn.logger.password=${spring.datasource.password}

# redis 的设置信息. 线上请用Redis Cluster
#spring.redis.host=127.0.0.1
#spring.redis.port=6379

#以debug级别,可以看到事务组处理时的一些日志情况
logging.level.root=debug

pom文件无需改动。启动redis server端后,如此TM就可以启动了。启动成功后,通过浏览器http://localhost:7970/admin/index.html#/login出现登录界面后,就说明TM已经正常部署好了。通过初始密码codingapi进入:

2.2.4 微服务启动

在自己的微服务项目中,首先在pom.xml文件中,添加TX-LCN框架依赖的核心包。如下:

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

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

其次,在项目的主启动类加上@EnableDistributedTransaction注解。每一个需要使用到分布式事务控制的项目都需要加上。

最后,在代码上,添加上事务框架的注解@LcnTransaction,@Transactional,如下:

@Override
@LcnTransaction//分布式事务
@Transactional //本地事务
public int updateUserInfo() {

    //先调用另一个服务的update操作
    User user1 = new User();
    user1.setId(1);
    user1.setAge(30); //原数据21
    int result1 = userService.updateUser(user1);
    log.info("第一个服务调用完成,result1="+result1);

    if(1<2){
        throw new  RuntimeException("我是测试分布式事务的异常。。。。");
    }

    //再调用本服务update操作
    User otherUser = new User();
    otherUser.setId(2);
    otherUser.setAge(33);//原数据25
    int result = userMapper.updateById(otherUser);
    log.info("来自11000的用户更新结果为:"+result);
    return result;
}

至此,整个框架整合基本完成。现在可以启动我们的项目,测试分布式事务是否有效啦。测试结果,我这边就不展示了,亲测有效,因为异常,会回滚第一个写操作的事务。

3.总结

TX-LCN分布式事务框架也分多种事务模式,其原理也是基于XA两端提交,TCC模式等实现。本次是分享是使用的LCN模式,虽然实现流程基本了解,但还没有分析过其源码。因为时间问题,其实最后还有一个疑问暂未解决:

在发生异常,分布式事务回滚后,数据表t_tx_exception中应该有写入相关记录,但是我在实践过程中却没有插入任何信息

学习分享的同时,也是相互取经的过程。希望有知道的大神或是朋友能够不吝赐教,本人也会后续跟进更新。

发布了43 篇原创文章 · 获赞 39 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/yy339452689/article/details/103871242