0%

分布式事务-LCN

LCN

Lock(锁定事务单元)、Confirm(确认事务)、Notify(通知事务)

TX-LCN定位于一款事务协调性框架,框架其本身并不操作事务,而是基于对事务的协调从而达到事务一致性的效果。

TM:事务管理器

TC:事务客户端,相当于RM(资源管理器)

核心步骤

  • 创建事务组
    是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程。
  • 加入事务组
    添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息通知给TxManager的操作。
  • 通知事务组
    是指在发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager,TxManager将根据事务最终状态和事务组的信息来通知相应的参与模块提交或回滚事务,并返回结果给事务发起方。

调用链路中的TC通过拦截器获取请求头中的事务组id,封装到TracingContext中,当封装创建TxContext时,会从TracingContext中取出事务id,用于跟TM交互

LCN事务模式

原理

当本地事务提交回滚或者关闭连接时将会执行假操作(没有真正释放连接),该代理的连接将交由TM的LCN连接池管理,在全部TC响应结果后,TM异步通知TC们“提交”或者“回滚”。

  • 该模式下的事务提交与回滚是由本地事务方控制,对于数据一致性上有较高的保障。
  • 该模式缺陷在于代理的连接需要随事务发起方一共释放连接,增加了连接占用的时间。

TM-TxManager(事务管理器)

集群模式下,直接启动多台TM

sql

数据库脚本位于txlcn-tm-5.0.2.RELEASE.jar包下的tx-manager.sql

1
2
3
4
5
6
7
8
9
10
11
12
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,
`ex_state` tinyint(4) NULL DEFAULT NULL COMMENT '0 待处理 1已处理',
`remark` varchar(10240) NULL DEFAULT NULL COMMENT '备注',
`create_time` datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 967 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
pom
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- tm-->
<dependency>
<groupId>com.codingapi.txlcn</groupId>
<artifactId>txlcn-tm</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- tc-->
<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>
properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# TM事务管理器的服务端WEB访问端口。提供一个可视化的界面。端口自定义。
server.port=7970

# TM事务管理器,需要访问数据库,实现分布式事务状态记录。
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/tx-manager?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

# TM事务管理器,是依赖Redis使用分布式事务协调的。尤其是TCC和TXC两种事务模型。
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database=0

# 为spring应用起名。
spring.application.name=tx-lcn-transaction-manager

# TM事务管理器,提供的WEB管理平台的登录密码。无用户名。 默认是codingapi
tx-lcn.manager.admin-key=msb
# 日志。如果需要TM记录日志。则开启,赋值为true,并提供后续的配置。
tx-lcn.logger.enabled=true

# 为日志功能,提供数据库连接。和之前配置的分布式事务管理依赖使用的数据源不同。
tx-lcn.logger.driver-class-name=com.mysql.cj.jdbc.Driver
tx-lcn.logger.jdbc-url=jdbc:mysql://localhost:3306/tx-manager?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
tx-lcn.logger.username=root
tx-lcn.logger.password=root
java

启动类

1
@EnableTransactionManagerServer

TC-TxClient(相当于RM资源管理器)

pom
1
2
3
4
5
6
7
8
9
10
11
12
<!-- tc -->
<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>
yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server:
port: 8083
spring:
application:
name: tx-lcn-order
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tx_order?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: 123
# mybaits-plus配置
mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml
configuration:
map-underscore-to-camel-case: true
#注册中心
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8081/eureka
fetch-registry: true
register-with-eureka: true
#lcn事务管理器连接
tx-lcn:
client:
manager-address: 127.0.0.1:8070 # tm地址,多个tm以英文逗号分隔
java

启动类

1
@EnableDistributedTransaction

业务类

1
@LcnTransaction

TCC事务模式

原理

TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务、 Confirm:确认执行业务、 Cancel: 取消执行业务。

TM

上同

TC

java

启动类

1
@EnableDistributedTransaction

业务类,添加@TccTransaction注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* try
*/
@GetMapping("/order/{orderName}")
@Transaction
@TccTransaction
public String order(@PathVariable String orderName) {
TxOrder order = new TxOrder();
order.setOrderName("tcc-order:" + orderName);
orderService.save(order);
// System.out.println(1/0);
log.info("tcc-order新增成功");
String payResult = restTemplate.getForObject("http://tx-lcn-pay/tcc/pay/" + orderName, String.class);
log.info("tcc-payResult ==>" + payResult);
return "tcc-order新增成功";
}

/**
* confirm
*/
public String confirmOrder(String orderName) {
System.out.println("order confirm ");
return "新增订单成功-confirm";
}

/**
* cancel
*/
public String cancelOrder(String orderName) {
System.out.println("order cancel ");
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("order_name", "tcc-order:" + orderName);
orderService.removeByMap(columnMap);
return "新增订单成功-cancel";
}