【分布式事务----LCN】LCN原理及使用方式
一、简介
LCN分布式事务框架其本身并不创建事务,而是基于对本地事务的协调从而达到事务一致性的效果。
LCN5.0.2有3种模式,分别是LCN模式,TCC模式,TXC模式
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模式消耗资源与时间要多。
- 该模式不会占用数据库的连接资源。
二、原理
核心步骤
1.创建事务组
是指在事务发起方开始执行业务代码之前先调用TxManager创建事务组对象,然后拿到事务标示GroupId的过程。
2.添加事务组
添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息添加通知给TxManager的操作。
3.关闭事务组
是指在发起方执行完业务代码以后,将发起方执行结果状态通知给TxManager的动作。当执行完关闭事务组的方法以后,TxManager将根据事务组信息来通知相应的参与模块提交或回滚事务。事务控制原理
LCN事务控制原理是由事务模块TxClient下的代理连接池与TxManager的协调配合完成的事务协调控制。
TxClient的代理连接池实现了javax.sql.DataSource接口,并重写了close方法,事务模块在提交关闭以后TxClient连接池将执行"假关闭"操作,等待TxManager协调完成事务以后在关闭连接。
对于代理连接池的优化
- 自动超时机制,任何通讯都有最大超时限制,参与模块在等待通知的状态下也有最大超时限制,当超过时间限制以后事务模块将先确认事务状态,然后再决定执行提交或者回滚操作,主要为了给最大资源占用时间加上限制。
- 智能识别创建不同的连接 对于只读操作、非事务操作LCN将不开启代理功能,返回本地连接对象,对于补偿事务的启动方将开启回滚连接对象,执行完业务以后马上回滚事务。
- LCN连接重用机制 当模块在同一次事务下被重复执行时,连接资源会被重用,提高连接的使用率。
事务补偿机制
为什么需要事务补偿?
事务补偿是指在执行某个业务方法时,本应该执行成功的操作却因为服务器挂机或者网络抖动等问题导致事务没有正常提交,此种场景就需要通过补偿来完成事务,从而达到事务的一致性。
补偿机制的触发条件?
当执行关闭事务组步骤时,若发起方接受到失败的状态后将会把该次事务识别为待补偿事务,然后发起方将该次事务数据异步通知给TxManager。TxManager接受到补偿事务以后先通知补偿回调地址,然后再根据是否开启自动补偿事务状态来补偿或保存该次切面事务数据。
补偿事务机制?
LCN的补偿事务原理是模拟上次失败事务的请求,然后传递给TxClient模块然后再次执行该次请求事务。模拟场景演示
若存在事务发起方、参与方A、参与方B。调用关系图如下
那么他们正常执行业务的时序图为:
若参与方B出现异常,那么他们的业务时序图为:
若他们的调用关系是这样的情况
此时发生参与方B出现异常时他们的时序图为:
三、使用
环境:
- SpringBoot 2.0.4
- SpringCloud(Eureka+Gateway) Finchley.SR3
- MySQL 5.7
- Redis
- LCN5.0.2
准备:
3.1搭建好Redis和MySQL
SQL建表语句(在txlcn-tm模块的resource目录下)
/*Navicat Premium Data TransferSource Server : localSource Server Type : MySQLSource Server Version : 100309Source Host : localhost:3306Source Schema : tx-managerTarget Server Type : MySQLTarget Server Version : 100309File Encoding : 65001Date: 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下载源码并编译
源码下载地址:https://github.com/codingapi/tx-lcn
工程目录
修改txlcn-tm的配置文件application.properties
####################### 服务 ############################################
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/306509906@qq.com
注意:个人修改了数据库的名称,和用户名密码,根据自己的实际情况修改
txlcn-tm的pom修改,放开配置
注掉配置
最后使用maven编译,去掉test,否则编译很慢
3.3启动txlcn-tm模块
不知道怎么启动的可以自行查阅Springboot运行方式
启动后打开后台地址http://localhost:7970,初始密码是codingapi,我这里改成了123456
登陆后
3.4项目配置
pom引用
<!-- 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>
配置文件增加事务管理中心地址
# LCN tx-lcn:client:manager-address: 127.0.0.1:8070logger: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
Consumer、Provider1、Provider2启动类增加注解
@EnableDistributedTransaction // 启用分布式事务
在Priovider1、Provider2要执行的方法上增加注解
@LcnTransaction //分布式事务注解 @Transactional //本地事务注解
最后运行 验证即可
【分布式事务----LCN】LCN原理及使用方式相关推荐
- 分布式事务的实现原理
点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 事务是数据库系统中非常有趣也非常重要的概念,它是数据库管理系统执行过程中的一个逻辑单元,它能够保证 ...
- mysql2阶段提交具体实现_ShardingSphere 4.x 分布式事务之实现原理
导览 本小节主要介绍ShardingSphere分布式事务的实现原理 两阶段XA事务 Seata柔性事务 两阶段事务-XA 实现原理 实现原理 ShardingSphere里定义了分布式事务的SPI接 ...
- 分布式事务解决方案和原理
分布式事务解决方案和原理 一. 背景: 我们知道, 在以前的 all-in-one 的项目开发模式下, 所有事务问题都是本地事务问题, 基本上利用mysql的优化方案和java提供的API, 可以解决 ...
- 【网站架构】一招搞定90%的分布式事务,实打实介绍数据库事务、分布式事务的工作原理应用场景
大家好,欢迎来到停止重构的频道.本期,我们来聊一下数据库事务以及分布式事务. 大家都在强调事务的重要性,而分布式事务也说是微服务必备的.但又说事务会影响性能,分布式事务更是很复杂的东西.使得大家都很迷 ...
- 与基础事务管理器的通信失败 存货申请_图文并茂讲解分布式事务的实现原理...
事务是数据库系统中非常有趣也非常重要的概念,它是数据库管理系统执行过程中的一个逻辑单元,它能够保证一个事务中的所有操作要么全部执行,要么全不执行:在 SOA 与微服务架构大行其道的今天,在分布式的多个 ...
- Redis分布式事务锁的原理(上)
我们在单机服务器,出现资源的竞争,一般使用synchronized 就可以解决,但是在分布式的服务器上,synchronized 就无法解决这个问题,这就需要一个分布式事务锁. 除此之外面试,基本会问 ...
- 分布式事务架构设计原理
随着业务需求的复杂化,企业应用规模不断扩大,在后端开发中经常会遇到以下问题: 业务的并发要求非常高,对应的业务需要通过微服务拆分,甚至分库分表等架构设计才能满足并发需求,此时业务操作无法在同一个数据库 ...
- 阿里分布式事务框架Seata原理解析
阿里分布式事务框架Seata原理解析 作者:伊凡的一天 链接:https://www.jianshu.com/p/044e95223a17 Seata框架是一个业务层的XA(两阶段提交)解决方案.在理 ...
- 分布式事务--TCC--流程/原理
原文网址:分布式事务--TCC--流程/原理_IT利刃出鞘的博客-CSDN博客 简介 本文介绍TCC分布式事务解决方案的流程及原理. 流程 详解 业务操作分两阶段完成 如下图所示,接入TCC前,业务操 ...
- 分布式事务框架Seata原理详解
本文来深度解析下分布式事务框架Seata原理,知其然知其所以然. 文章目录 Seata概述 什么是2PC二阶段提交协议 MySQL XA方案 Seata核心知识 Seata设计目标 Seata组成结构 ...
最新文章
- HTTP协议详解(真的很经典)
- Ubuntu16.04安装CUDA8.0时,提示:The driver installation is unable to locate the kernel source.
- aix 5.3 安装oracle 10g r2,在AIX5上安装ORACLE10G R2的步骤
- CString转char*
- dbcp连接池配置参数
- Matplotlib模块的使用
- MVC数据验证Model Validation
- 为.net开发者提供的一份关于存储过程的评论(转载)
- Android安全补丁程序下载,2017年一月win7安全补丁更新包官方下载-2017Win7安全更新补丁包64位下载-西西软件下载...
- 图片标注工具LabelImg使用教程
- 通过libxml2的xpath解析xml
- 计算机桌面图标变小了,电脑桌面图标变小了怎么办
- SATA硬盘分区设置与安装详解
- python乘法口诀表
- linux平台MSG_OOB选项测试
- 目标检测综述(二:古典方法对比现代方式以及目标检测算法相关概述)
- 【转载】PCB layout工程师级别(可以留着自评用~~)
- python turtle 绘制七段数码管以及14段数码管显示字母和时间
- Word VBA自动排版(2)-通过自动查找替换去除叠字
- wpdec函数_BP神经网络滚动轴承故障诊断研究
热门文章
- 有没有谁做过完整的ptf上传下载
- html背景渐变蓝色,CSS3网页渐变色背景,适用于IE
- CS《Combining Label Propagation and Simple Models Out-performs Graph Neural Networks》理论与实战
- 重复线性渐变repeating-linear-gradient
- 简易个人所得税计算器
- Internet选项里没有常规选项卡
- 使用vue3+vite+cesium,在地图上显示图标,并且点击实体弹出消息框
- 傅立叶级数到傅立叶变换推导与理解
- 纯电动汽车整车控制器(VCU)详细介绍
- qq服务器传输文件,QQ离线传文件功能简介