1、概述

TX-LCN 主要有两个模块: Tx-Manager™,Tx-Client(TC) 。TM是管理端,独立的服务;TC就是我们自己的微服务。需要创建一个数据库和一张表。

drop database if exists `tx-manager`;
create database `tx-manager`; 
use `tx-manager`;
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、创建Tx-Manager

这是一个单独的服务,可以集成在Springcloud中,也可以单独部署。但是,目前最新的maven包5.0.2启动要求比较严格,比如:必须要用application.properties,不能使用yml格式,还有其他要求,总之,不要轻易去更改配置内容,否则就是启动报错。以下以集成在Springcloud为例,新建一个module,项目结构也相对简单。

spring保存分布式session到redis_springcloud


spring保存分布式session到redis_springcloud_02


启动类另加一个注解@EnableTransactionManagerServer,如下

spring保存分布式session到redis_spring_03

pom.xml 中 添加一个依赖,

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

引用父依赖,以实际的项目为准,参考其他module配置

spring保存分布式session到redis_redis_04


如果是单独部署,则可以是

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

最重要的是application.properties文件

spring.application.name=t1-service
server.port=7970

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tx-manager?serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
# 记录异常记录
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=update

mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.use-generated-keys=true

# TxManager Host Ip
tx-lcn.manager.host=127.0.0.1
# 后台管理页面登录密码
tx-lcn.manager.admin-key=123456
# 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=XXXXXXXX
#redis 端口
spring.redis.port=6379
#redis 密码
spring.redis.password=XXXXXXXX

注意,redis的配置按实际地址配置,也需要预先启动。文件格式不要改成yml格式,否则会启动不了,以上就能单独启动TM服务了,不用再更改其他内容。

3、添加TC配置

这个相对简单些,有几个微服务涉及到事务控制,都要分别配置
在每个微服务的pom.xml添加2个依赖

<!--lcn事务-->
<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>

1、在启动类上添加注解@EnableDistributedTransaction
2、在controller层添加注解@LcnTransaction,@Transactional
3、添加配置信息,manager-address地址和以上TM中的配置一致,logger可以删除,联调环境最好开启。

# 默认之配置为TM的本机默认端口
tx-lcn:
  client:
    manager-address: 127.0.0.1:8070
# 开启日志,默认为false
  logger:
    enabled: true
    driver-class-name: com.mysql.jdbc.Driver
    jdbc-url: jdbc:mysql://127.0.0.1:3306/tx-manager?serverTimezone=UTC&characterEncoding=UTF-8
    username: root
    password: root
    level.com.codingapi.txlcn: DEBUG

到此为止,配置就好了。

演示

后台管理页面登录地址:http://127.0.0.1:7970,密码:123456,TM配置中有写,我这边配置了2个微服务,就显示2个注册的TC。

spring保存分布式session到redis_redis_05


演示代码如下:

spring保存分布式session到redis_分布式事务_06


以上调用服务之后,2个库都没插入新数据(回滚了),演示成功。

spring保存分布式session到redis_redis_07

有人提出疑问了,这个异常记录是用来干嘛的,或者说新建的数据库中表没记录数据,感觉也没什么用。原因是因为它是用来记录“异常数据”。演示步骤如下:

1、更改代码

2、设置断点

3、执行到断点,断开另一个服务

4、放开断点,执行完代码(就会产生一条记录)

大致过程:通知另一个服务执行事务时,服务挂了,事务没有得到执行,就会成一条异常记录。

spring保存分布式session到redis_LCN_08


spring保存分布式session到redis_分布式事务_09


由此可见,这种用异常日志来记录事务的异常执行情况。