天天看点

TX-LCN解决微服务分布式事务问题

前言

上一篇文章写了微服务分布式事务问题的示例

https://blog.csdn.net/daziyuanazhen/article/details/100825240

这里在上一篇的代码基础上,引入TX-LCN框架解决分布式事务问题。

TX-LCN框架

原理

创建一个事务协调者,事务的发起方创建一个事务组,会有一个组id,事务的参与方会加入事务组,当某个组成员发生异常的时候,会通知事务协调者,事务协调者则会通知所有组员进行事务回滚。

TX-LCN解决微服务分布式事务问题

核心步骤

  • 创建事务组

    是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程。

  • 加入事务组

    添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息通知给TxManager的操作。

  • 通知事务组

    是指在发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager,TxManager将根据事务最终状态和事务组的信息来通知相应的参与模块提交或回滚事务,并返回结果给事务发起方。

TX-LCN解决微服务分布式事务问题

发起方(订单服务)和参与方(库存服务)都必须注册到事务协调者(TxManager)中,建立一个长连接。

发起方调用参与方之前会向事务协调者创建一个事务的分组id。

发起方调用参与方的时候,会在请求头中存放该事务的分组id给参与方。

如果参与方获取到请求头中有对应的事务分组id,参与方业务逻辑代码执行完毕的,会采用假关闭,不会提交该事务。

当发起方执行成功后,会使用对应的分组id通知给事务协调者,协调者在通知所有参与方提交事务。

长连接的好处是减少宽带传输,弊端是比较占内存。

官网https://www.txlcn.org/zh-cn/

可以在gihub上下载框架代码,地址是https://github.com/codingapi/tx-lcn/releases

这里我们下载的是

TX-LCN解决微服务分布式事务问题

解压之后,使用idea导入项目

TX-LCN解决微服务分布式事务问题
TX-LCN解决微服务分布式事务问题

之后一直点下一步,就完成了项目的导入

项目的目录是这样的

TX-LCN解决微服务分布式事务问题

我们需要对txlcn-tm项目进行配置的修改,其他模块不需要修改

TX-LCN解决微服务分布式事务问题

创建数据库的语句在项目里有

TX-LCN解决微服务分布式事务问题

修改application.properties配置文件的mysql配置,配置成自己的mysql地址和帐号密码

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
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=update


#tx-lcn.logger.enabled=true
# TxManager Host Ip
#tx-lcn.manager.host=127.0.0.1
# TxClient连接请求端口
#tx-lcn.manager.port=8070
# 心跳检测时间(ms)
#tx-lcn.manager.heart-time=15000
# 分布式事务执行总时间
#tx-lcn.manager.dtx-time=30000
#参数延迟删除时间单位ms
#tx-lcn.message.netty.attr-delay-time=10000
#tx-lcn.manager.concurrent-level=128
# 开启日志
#tx-lcn.logger.enabled=true
#logging.level.com.codingapi=debug
#redis 主机
#spring.redis.host=127.0.0.1
#redis 端口
#spring.redis.port=6379
#redis 密码
#spring.redis.password=
           

前面用#注释了的配置都是默认配置的默认值,如果需要修改的话就需要去掉注释进行修改,这里我们redis是在本地的,不需要进行修改。

启用springboot入口类

TX-LCN解决微服务分布式事务问题

启动之后若没有报错,就说明启动成功了,可以在浏览器打开控制台

http://localhost:7970/

默认密码是codingapi

TX-LCN解决微服务分布式事务问题

到这里就完成了TX-LCN的服务端,接下来是修改微服务去注册TX-LCN的TC

在上一篇博客的代码基础上进行修改

https://blog.csdn.net/daziyuanazhen/article/details/100825240

订单服务和库存服务统一修改

添加依赖

<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>
           

在application.properties添加配置

tx-lcn.client.manager-address=127.0.0.1:8070    
           

这里的配置是指定TX-LCN服务端的地址

在springboot入口类添加注释

@EnableDistributedTransaction
           

在业务接口实现类方法添加注释@LcnTransaction

@LcnTransaction
    @Override
    public void addOrder() {
        orderMapper.addOrder();
        System.out.println("添加订单成功");
        serviceBFeign.reduceStock();
        System.out.println("调用库存服务减库存成功");

        System.out.println("出现异常,事务回滚");
        int i = 1/0;

    }
           

先后启动TX-LCN服务端、微服务注册中心、订单服务和库存服务

浏览器访问http://localhost:8081/order/addOrder

可以发现订单服务和库存服务都进行事务回滚了。

这样就解决了微服务的分布式事务问题。

继续阅读