技术经验解读:三种分布式事务LCN、Seata、MQ

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 技术经验解读:三种分布式事务LCN、Seata、MQ

分布式事务存在的原因:数据分布在不同的数据库实例。一个分布式系统下存在多个模块协调来完成一次业务,每一个模块对应一个数据源,同一个业务需要操作不同的模块,改动不同的数据库,要么都成功,要么都失败。


举例:


去A库中存储老师实体类的数据


?1234567@Datapublic class Teacher{ @Id private Integer tid; @Field private String tname;}


去B库中存储学生实体类的数据


?12345678910@Data@Documentpublic class Teacher{ @Id private String id; @Field privtae String name; @Field private Integer tid;}


这两个pojo类通过tid关联,学生对老师是一对多的关系,两个POJO的数据通过mysql存储在两个不同的类。


常见的分布式框架解决方案


全局事务2pc --关系型数据库


缺点:效率低,算法执行过程中,所有的节点处于阻塞状态,所有节点所持有的资源处于封锁状态。


3pc(三段提交协议)


消息中间件


提供回滚接口


为了方便我们了解分布式事务框架,我们需要先了解的相关说明。


Spring本地事务是在同一个系统里做的实务操作,需要符合数据库事务ACID特性,为刚性事务;而分布式事务往往不能满足ACID,不同的数据库实例对同一个方法在一个时间的响应并不完全一样,但可能最终一致,这种事务是柔性事务。


柔性事务定理了解


1. CAP定理


一个分布式系统于事务由三个特性:Consistency(一致性) 、Availability(可用性)、 Partition tolerance(分区容错性)。现实情况下,分布式系统最多同时满足其中两个,不能同时满足三个。


可用性和一致性是矛盾的,原因是在分布式事务中操作多个节点的时候,一个节点坏了还得有别的节点来承担,这是为了满足可用性,但不符合一致性。


分区容错性意思是,系统不能在一定时限内达到数据的一致性,就意味着发生了分区的情况。假设在一定时间内,A节点和C节点没能同步数据,那么框架需要决定到底是A版本还是C版本作为后续操作数据的基版。


2. BASE理论


CAP理论的优化。Basically Available(基本可用 )、soft state(软状态),Eventually consistent(最终一致性)三个短语的缩写。


BASE理论要求,即使无法做到节点强一致,但每个分布式应用都可以根据自身业务特点,采用适当的方式达到最终一致性。


BA基本可用:指分布式系统中出现不可知故障的时候,允许损失部分可用性,但不代表整个系统不可用。(比如秒杀活动的并发降级页面)


S软状态:系统中数据允许存在中间状态(软状态),并认为这个状态不影响可用性,允许分布式节点之间存在同步延迟。(如Eureka集群同步数据)


最终一致性:允许整个系统数据在经过一定时间后,最终能达到整个系统的一致性。为弱一致性,响应给用户结果时整个系统没有达到一致性,但最终一定会达到一致性的。


强一致性:系统接受请求后,整个系统必须达到一致的结果才能响应。


根据不同的解决方案衍生出了不同的分布式事务技术,下面介绍不同的分布式技术在这个示例的表现。


LCN


介绍


XA两阶段提交协议


第一阶段所有的参与者TC(Transaction Client)准备执行事务并锁住需要的资源,并向事务管理器报备自己已经准备好。


第二阶段事务管理器负责协调,向不同的RM(资源管理器)索要数据,尽可能晚提交事务(在提交之前完成所有的工作),但也要等待TM(Transaction Manager)响应容易阻塞。吞吐量优先,不适合互联网。


三种模式


基于XA两阶段提交协议,现存LCN分布式事务框架有三种模式,分别是LCN模式,TCC模式,TXC模式。


1. LCN模式:基于jdbc关系型数据库实现对本地事务的操作,然后在由TM(Transaction Manager)统一协调控制事务。当本地事务提交回滚或者关闭连接时将会执行假操作,该代理的连接将由LCN连接池管理。基于注解 @LcnTransaction。


2. TCC模式:基于非关系型数据库(非关系型就是非事务性,除此之外也支持关系型数据库),相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三阶段完成,Try: 尝试执行业务、 Confirm:确认执行业务、 Cancel: 取消执行业务。特点:完全依赖开发者,通过重写三个方法来实现对事务的控制,基于注解@TccTransaction。


3. TXC模式:命名来源于淘宝,实现原理是在执行SQL之前,先查询SQL的影响数据,然后保存执行的SQL快走信息和创建锁。当需要回滚的时候就采用这些记录数据回滚数据库,目前锁实现依赖redis分布式锁控制。特点:嵌入低,不会占用数据库的连接资源,资源消耗较多,基于注解@TxcTransaction。


LCN原理解析


事务发起方和参与方都属于TxClient,TxManager负责控制整个事务。


123代表三个txClient将自己的事务发布到TxManager,4为发起方告诉txManager获取数据成功或者失败,如果成功(其中一个失败也算失败),TxManager返回通知AB让他们各自提交自己的事务。5为txManager通知发起方提交自己的事务。


LCN事务核心步骤


1. 创建事务组:事务发起方在开始执行业务代码之前先调用txManager创建事务组对象,拿到事务表示GroupId。


2. 加入事务组:2和3,参与方将自己的事务执行情况报备给txManager


3. 通知事务组:发起方执行完业务代码之后,将执行结果状态通知给txManager


4. 通知事务单元:txManager询问参与方的事务执行结果


5. 响应通知事务组:txManager通知发起方事务的最终结果


配置Tx-LCN案例


一、新建


1. 执行依赖中带有的tx-manager.sql文件到数据库中


2. 配置application.properties


TC配置


# 是否启动LCN负载均衡策略(优化选项,开启与否,功能不受影响)


tx-lcn.ribbon.loadbalancer.dtx.enabled=true


# tx-manager 的配置地址,可以指定TM集群中的任何一个或多个地址


# tx-manager 下集群策略,每个TC都会从始至终[/span>断线重连

# TM方,每有TM进入集群,会找到所有TC并通知其与新TM建立连接。


# TC方,启动时按配置与集群建立连接,成功后,会再与集群协商,查询集群大小并保持与所有TM的连接


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


# 该参数是分布式事务框架存储的业务切面信息。采用的是h2数据库。绝对路径。该参数默认的值为{user.dir}/.txlcn/{application.name}-{application.port}


tx-lcn.aspect.log.file-path=logs/.txlcn/demo-8080


# 调用链长度等级,默认值为3(优化选项。系统中每个请求大致调用链平均长度,估算值。)


tx-lcn.client.chain-level=3


# 该参数为tc与tm通讯时的最大超时时间,单位ms。该参数不需要配置会在连接初始化时由tm返回。


tx-lcn.client.tm-rpc-timeout=2000


# 该参数为分布式事务的最大时间,单位ms。该参数不允许TC方配置,会在连接初始化时由tm返回。


tx-lcn.client.dtx-time=8000


# 该参数为雪花算法的机器编号,所有TC不能相同。该参数不允许配置,会在连接初始化时由tm返回。


tx-lcn.client.machine-id=1


# 该参数为事务方法注解切面的orderNumber,默认值为0.


tx-lcn.client.dtx-aspect-order=0


# 该参数为事务连接资源方法切面的orderNumber,默认值为0.


tx-lcn.client.resource-order=0


# 是否开启日志记录。当开启以后需要配置对应logger的数据库连接配置信息。


tx-lcn.logger.enabled=false


tx-lcn.logger.driver-class-name=${spring.datasource.driver-class-name}


tx-lcn.logger.jdbc-url=${spring.datasource.url} #jdbc:mysql://localhost:3306/tx-manager?characterEncoding=UTF-8 遇上servertimezone问题添加serverTimezone=GMT


tx-lcn.logger.username=${spring.datasource.username}


tx-lcn.logger.password=${spring.datasource.password}


tx-lcn.logger.enabled=false #如果打开事务:更改 tx-lcn.logger.enabled=true


TM配置


spring.application.name=TransactionManager


server.port=7970


# JDBC 数据库配置


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


# 第一次运行可以设置为: create, 为TM创建持久化数据库表


spring.jpa.hibernate.ddl-auto=validate


# 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=codingapi


# 分布式事务锁超时时间 默认为-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/**@.com


# 开启日志,默认为false


tx-lcn.logger.enabled=true


tx-lcn.logger.enabled=false


tx-lcn.logger.driver-class-name=${spring.datasource.driver-class-name}


tx-lcn.logger.jdbc-url=${spring.datasource.url}


tx-lcn.logger.username=${spring.datasource.username}


tx-lcn.logger.password=${spring.datasource.password}


# redis 的设置信息. 线上请用Redis Cluster


spring.redis.host=127.0.0.1


spring.redis.port=6379


spring.redis.password=


配置本地事务和分布式事务


@Configuration


@EnableTransactionManagement


public class TransactionConfiguration {


/


本地事务配置


@param transactionManager


@return


/


@Bean


@ConditionalOnMissingBean


public TransactionInterceptor transactionInterceptor(PlatformTransactionManager transactionManager) {


Properties properties = new Properties();


properties.setProperty("", "PROPAGATION_REQUIRED,-Throwable");


TransactionInterceptor transactionInterceptor = new TransactionInterceptor();


transactionInterceptor.setTransactionManager(transactionManager);


transactionInterceptor.setTransactionAttributes(properties);


return transactionInterceptor;


}


/**


分布式事务配置 设置为LCN模式


@param dtxLogicWeaver


@return


/


@ConditionalOnBean(DTXLogicWeaver.class)


@Bean


public TxLcnInterceptor txLcnInterceptor(DTXLogicWeaver dtxLogicWeaver) {


TxLcnInterceptor txLcnInterceptor = new TxLcnInterceptor(dtxLogicWeaver);


Properties properties = new Properties();


properties.setProperty(Transactions.DTX_TYPE,Transactions.LCN);


properties.setProperty(Transactions.DTX_PROPAGATION, "REQUIRED");


txLcnInterceptor.setTransactionAttributes(properties);


return txLcnInterceptor;


}


@Bean


public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {


BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();


//需要调整优先级,分布式事务在前,本地事务在后。


beanNameAutoProxyCreator.setInterceptorNames("txLcnInterceptor","transactionInterceptor");


beanNameAutoProxyCreator.setBeanNames("Impl");


return beanNameAutoProxyCreator;


}


}


二、依赖


TX-Manager配置,独立于微服务,是独立的依赖


[/span>dependencies

[/span>dependency

[/span>groupId

[/span>artifactId


[/span>dependency

[/span>groupId

[/span>artifactId


[/span>dependency

[/span>groupId

[/span>artifactId

[/span>scope


[/span>dependency

[/span>groupId

[/span>artifactId

[/span>version



[/span>dependencyManagement

[/span>dependencies

[/span>dependency

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
打赏
0
0
0
0
43
分享
相关文章
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
3月前
|
如何在Seata框架中配置分布式事务的隔离级别?
总的来说,配置分布式事务的隔离级别是实现分布式事务管理的重要环节之一,需要认真对待和仔细调整,以满足业务的需求和性能要求。你还可以进一步深入研究和实践 Seata 框架的配置和使用,以更好地应对各种分布式事务场景的挑战。
149 63
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
222 53
微服务SpringCloud分布式事务之Seata
SpringCloud+SpringCloudAlibaba的Seata实现分布式事务,步骤超详细,附带视频教程
79 1
从零到一:分布式缓存技术初探
分布式缓存通过将数据存储在多个节点上,利用负载均衡算法提高访问速度、降低数据库负载并增强系统可用性。常见产品有Redis、Memcached等。其优势包括性能扩展、高可用性、负载均衡和容错性,适用于页面缓存、应用对象缓存、状态缓存、并行处理、事件处理及极限事务处理等多种场景。
199 1
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
121 2
大厂都在用的分布式事务方案,Seata+RocketMQ带你打破10万QPS瓶颈
分布式事务涉及跨多个数据库或服务的操作,确保数据一致性。本地事务通过数据库直接支持ACID特性,而分布式事务则需解决跨服务协调难、高并发压力及性能与一致性权衡等问题。常见的解决方案包括两阶段提交(2PC)、Seata提供的AT和TCC模式、以及基于消息队列的最终一致性方案。这些方法各有优劣,适用于不同业务场景,选择合适的方案需综合考虑业务需求、系统规模和技术团队能力。
396 7
Seata框架和其他分布式事务框架有什么区别
Seata框架和其他分布式事务框架有什么区别
55 1
深度解析区块链技术的分布式共识机制
深度解析区块链技术的分布式共识机制
101 0
基于Seata实现分布式事务
通过以上步骤,你可以使用 Seata 实现分布式事务,确保在微服务架构中的事务一致性。Seata 支持多种语言和框架,能够满足不同业务场景的需求。欢迎关注威哥爱编程,一起学习成长。
234 1
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等