[Distributed transaction-LCN] LCN principle and usage

1. Introduction

The LCN distributed transaction framework itself does not create transactions, but is based on the coordination of local transactions to achieve the effect of transaction consistency.

LCN5.0.2 has 3 modes, namely LCN mode, TCC mode, TXC mode

LCN模式:

LCN模式是通过代理Connection的方式实现对本地事务的操作,然后在由TxManager统一协调控制事务。当本地事务提交回滚或者关闭连接时将会执行假操作,该代理的连接将由LCN连接池管理。
该模式的特点:

    - 该模式对代码的嵌入性为低。
    - 该模式仅限于本地存在连接对象且可通过连接对象控制事务的模块。
    - 该模式下的事务提交与回滚是由本地事务方控制,对于数据一致性上有较高的保障。
    - 该模式缺陷在于代理的连接需要随事务发起方一共释放连接,增加了连接占用的时间。
     

TCC模式:

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

该模式的特点:

    - 该模式对代码的嵌入性高,要求每个业务需要写三种步骤的操作。
    - 该模式对有无本地事务控制都可以支持使用面广。
    - 数据一致性控制几乎完全由开发者控制,对业务开发难度要求高。
     

TXC模式:
TXC模式命名来源于淘宝,实现原理是在执行SQL之前,先查询SQL的影响数据,然后保存执行的SQL快走信息和创建锁。当需要回滚的时候就采用这些记录数据回滚数据库,目前锁实现依赖redis分布式锁控制。
该模式的特点:

    - 该模式同样对代码的嵌入性低。
    - 该模式仅限于对支持SQL方式的模块支持。
    - 该模式由于每次执行SQL之前需要先查询影响数据,因此相比LCN模式消耗资源与时间要多。
    - 该模式不会占用数据库的连接资源。

Second, the principle
core steps

1. Creating a transaction group
refers to the process of calling TxManager to create a transaction group object before the transaction initiator starts to execute the business code, and then getting the transaction identification GroupId.
2. Adding a transaction group
Adding a transaction group refers to the operation of adding and notifying TxManager of the transaction information of the module after the participants have finished executing the business method.
3. Closing the transaction group
refers to the action of notifying the initiator of the execution result status to the TxManager after the initiator finishes executing the business code. After executing the method of closing the transaction group, TxManager will notify the corresponding participating modules to commit or roll back the transaction according to the transaction group information.
Principles of Transaction Control

The LCN transaction control principle is the transaction coordination control completed by the coordination of the agent connection pool under the transaction module TxClient and the TxManager.

TxClient's proxy connection pool implements the javax.sql.DataSource interface and rewrites the close method. After the transaction module commits and closes, the TxClient connection pool will perform a "false close" operation, waiting for TxManager to coordinate and complete the transaction before closing the connection.
Optimization of proxy connection pool

自动超时机制,任何通讯都有最大超时限制,参与模块在等待通知的状态下也有最大超时限制,当超过时间限制以后事务模块将先确认事务状态,然后再决定执行提交或者回滚操作,主要为了给最大资源占用时间加上限制。
智能识别创建不同的连接 对于只读操作、非事务操作LCN将不开启代理功能,返回本地连接对象,对于补偿事务的启动方将开启回滚连接对象,执行完业务以后马上回滚事务。
LCN连接重用机制 当模块在同一次事务下被重复执行时,连接资源会被重用,提高连接的使用率。

Transaction compensation mechanism

Why do you need transaction compensation?

Transaction compensation means that when a certain business method is executed, a successful operation should be performed but the transaction is not submitted normally due to problems such as server hang-up or network jitter. In this scenario, compensation is required to complete the transaction to achieve transaction consistency. .

What is the trigger condition of the compensation mechanism?

When the step of closing the transaction group is executed, if the initiator accepts the failed state, the transaction will be recognized as a transaction to be compensated, and then the initiator will asynchronously notify the TxManager of the transaction data. After receiving the compensation transaction, TxManager first notifies the compensation callback address, and then compensates or saves the transaction data of this aspect according to whether the automatic compensation transaction status is turned on.

Compensation transaction mechanism?
The principle of the compensation transaction of LCN is to simulate the request of the last failed transaction, and then pass it to the TxClient module and then execute the requested transaction again.
Simulation scene demonstration

If there is a transaction initiator, participant A, and participant B. The call relationship diagram is as follows

Then the sequence diagram of their normal business execution is:

If participant B is abnormal, then their business sequence diagram is:

If their calling relationship is like this

At this time, when participant B has an abnormality, their sequence diagram is as follows:
3. Use

surroundings:

SpringBoot 2.0.4
SpringCloud(Eureka+Gateway) Finchley.SR3
MySQL 5.7
Redis
LCN5.0.2

Preparation:
3.1 Build Redis and MySQL

SQL table creation statement (under the resource directory of the txlcn-tm module)

/*
 Navicat Premium Data Transfer
 Source Server         : local
 Source Server Type    : MySQL
 Source Server Version : 100309
 Source Host           : localhost:3306
 Source Schema         : tx-manager
 Target Server Type    : MySQL
 Target Server Version : 100309
 File Encoding         : 65001
 Date: 29/12/2018 18:35:59
*/
CREATE DATABASE IF NOT EXISTS  `tx-manager` DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
USE `tx-manager`;
 
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
 
-- ----------------------------
-- Table structure for t_tx_exception
-- ----------------------------
DROP TABLE IF EXISTS `t_tx_exception`;
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;
 
SET FOREIGN_KEY_CHECKS = 1;

3.2 Download the source code and compile

Source code download address: https://github.com/codingapi/tx-lcn

Project catalog

Modify the configuration file application.properties of txlcn-tm

####################### 服务 ############################################
 
spring.application.name=TransactionManager
server.port=7970
 
####################### 数据库 ############################################
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://47.92.145.192:3306/scm_transaction?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
spring.datasource.username=db_user2
spring.datasource.password=db_pass
# 验证连接是否有效。此参数必须设置为非空字符串,下面三项设置成true才能生
spring.datasource.validationQuery=SELECT 1
# 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
spring.datasource.testWhileIdle=true
# 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
spring.datasource.testOnBorrow=true
# 指明是否在归还到池中前进行检验
spring.datasource.testOnReturn=false
 
# 以下可省略
# 初始化大小,最小,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=10
spring.datasource.maxActive=1000
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
#配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
#打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
#配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall,log4j
#通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=1000;druid.stat.logSlowSql=true
#合并多个DruidDataSource的监控数据
spring.datasource.useGlobalDataSourceStat=true
#spring.datasource.WebStatFilter.exclusions="*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
#spring.datasource.stat-view-servlet.login-username=admin
#spring.datasource.stat-view-servlet.login-password=admin
 
####################### 数据库方言 ############################################
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
# 第一次运行可以设置为: create, 为TM创建持久化数据库表
spring.jpa.hibernate.ddl-auto=update
 
####################### Redis ############################################
spring.redis.host=47.92.145.192
spring.redis.port=6379
spring.redis.password=WZTH@dev123
 
####################### 事务 ############################################
# 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=123456
# 分布式事务锁超时时间 默认为-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/[email protected]

Note: Personally modified the name of the database, and the user name and password, modified according to their actual situation

Pom modification of txlcn-tm, release configuration

Annotate the configuration

Finally use maven to compile, remove the test, otherwise the compilation will be very slow

3.3 Start the txlcn-tm module

If you don't know how to start, you can check the Springboot running mode by yourself

After startup, open the background address http://localhost:7970, the initial password is codingapi, I changed it to 123456 here

After login

3.4 Project configuration

pom reference

            <!-- 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>
            <dependency>
                <groupId>com.codingapi.txlcn</groupId>
                <artifactId>txlcn-tm</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>

Add transaction management center address to configuration file

# LCN
tx-lcn:
    client:
        manager-address: 127.0.0.1:8070
    logger:
        enabled: true
#        driver-class-name: com.mysql.jdbc.Driver
#        jdbc-url: jdbc:mysql://47.92.145.192:3306/scm_transaction?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
#        username: db_user2
#        password: db_pass

Add annotations to the startup classes of Consumer, Provider1, and Provider2

@EnableDistributedTransaction // Enable distributed transaction

Add annotations to the methods to be executed by Priovider1 and Provider2

@LcnTransaction //分布式事务注解
@Transactional //本地事务注解

Finally, run the verification

Guess you like

Origin blog.csdn.net/qq_34117294/article/details/114986641