一、基于XA的两阶段提交方案两阶段提交方案应用非常广泛,大多数商业OLTP数据库支持XA协议。 但是,两阶段提交方案锁定资源的时间长,对性能影响大,几乎不适合解决微服务事务问题。
二、TCC解决方案TCC解决方案多在电子商务、金融领域落地。 TCC方案其实是两阶段提交的改进。 将整个业务逻辑的各分支明确分为Try、Confirm、Cancel三个操作。 Try部分完成业务准备,confirm部分完成业务提交,cancel部分完成业务回滚。 基本原理如下图所示。
事务启动后,业务APP应用程序将在事务协调器中注册启动事务。 然后,业务APP应用程序调用所有服务的try接口,完成一个阶段的准备。 然后,事务协调器根据try接口的返回情况决定调用confirm接口或cancel接口。 如果接口调用失败,将重试。
微服务提倡服务轻量化、易于部署,但TCC方案需要自行编码实现许多事务的处理逻辑,复杂且开发量大。
三.分布式事务中间件解决方案分布式事务中间件基于本地事务协调实现事务一致性,而不是自身创建事务。 代表性的是蚂蚁GTS (https://www.a liyun.com/Ali ware/txc )、开源APP应用LCN。
其实现原理如下
LCN分布式事务框架a .对于设计框架的初始版本1.0 ~ 2.0,框架设计过程如下,并对从每个开头字符得出的LCN进行命名。 事务单元锁定(lock )、事务模块状态确认(confirm )、事务通知(notify )。
b .创建事务组:在事务启动者开始执行业务代码之前,调用TxManager创建事务组对象并获取事务标签GroupId的过程。
c .添加事务组:添加事务组是指参与者执行业务方法后,将该模块的事务信息添加通知TxManager的操作。
d .关闭事务组—一种操作,用于在启动器运行业务代码后通知TxManager启动器运行结果的状态。 当您执行关闭事务组的方法时,TxManager会根据事务组的信息通知参与模块提交或回退事务
tx-lcn官方地址: https://www.txlcn.org/
tx-lcn Github地址: https://github.com/coding API/tx-lcn
tx-lcn服务下载地址: https://pan.Baidu.com/s/1 clk aee # list/path=/
tx-lcn服务源地址: https://github.com/coding API/tx-lcn/tree/master/tx-manager
lcn APP应用程序-tx-manager服务通过独立的微服务tx-manager充当分布式事务控制服务器(事务协调器)。 所有需要分布式事务控制的微服务APP应用程序都使用远程服务调用在tx-manager中标记事务组,并在执行事务后将本地事务的状态标记为tx-manager的相应事务
tx-manager也是使用Spring Cloud开发的微服务APP,在构建过程中非常简单。
tx-manager事务协调器zip压缩包下载: https://pan.Baidu.com/s/1 clk aee # list/path=/
解压缩压缩包的内容如下
修改application.properties配置文件以提供本地微服务APP应用程序的Eureka注册中心配置和redis配置。 其中,redis是事务协调器处理事务组时使用的临时存储
# # # # 不能更改spring.resources.static # # # # # # # # # txmanager-end # # # # # # # # # # eureka地址eureka. # # # # #
0spring.redis.pool.min-idle=50spring.redis.pool.timeout=600##############################redis-end#########################################################LCN-start########################tm.transaction.netty.delaytime = 5tm.transaction.netty.hearttime = 15tm.redis.savemaxtime=30tm.socket.port=9999tm.socket.maxconnection=100tm.compensate.auto=falsetm.compensate.notifyUrl=http://ip:port/pathtm.compensate.tryTime=30tm.compensate.maxWaitTime=5000logging.level.com.codingapi=debug将修改后的application.properties配置文件打包到tx-manager-x.x.x.jar中,替代jar中原有的默认配置文件。
使用命令: java -jar tx-manager-x.x.x.jar启动微服务。
测试tx-manager事务协调器是否启动成功可以访问http://ip:8899/。如下结果代表事务协调器启动成功
在微服务中使用LCN实现分布式事务管理
在所有需要处理分布式事务的微服务中增加下述依赖:为统一资源版本,使用properties统一管理版本信息
在全局配置文件中增加下述配置
# 定义事务协调器所在位置。根据具体环境定义其中的IP地址和端口。tm.manager.url=http://127.0.0.1:8899/tx/manager/使用LCN做分布式事务管理时,微服务应用内必须提供一个用于获取txUrl(txUrl就是全局配置文件中定义的tm.manager.url)的类型实现,这个类可以使用独立应用定义,在微服务应用中引入。本案例中为了方便,直接在所有的微服务应用中提供对应代码实现。具体如下
@Servicepublic class TxManagerTxUrlServiceImpl implements TxManagerTxUrlService {@Value("${tm.manager.url}")private String url;@Overridepublic String getTxUrl() {return url;}}在分布式事务管理代码中增加注解@TxTransaction。在业务调用方增加的注解需要属性isStart=true。而被调用方则不需要定义任何的注解属性。如:
交易服务调用了订单服务,那么交易服务中代码
订单服务中代码
@Transactional@TxTransactionpublic void order() { //本地调用 orderDao.save();}