分布式事务XA与JTA分布式事务解决方案

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。

前言

事务被用来解决或者说是挽救一下分布式系统中的数据一致性问题,首先来了解一下使用XAJTA方案来实现分布式事务

分布式场景

image.png

在一个微服务电商项目中,常见的业务场景之一。当我们的订单服务完成下单操作后,调用积分服务积分增加,调用库存服务库存减少,因为服务间通信,我们无法排除网络波动等一系列不确定因素,可能会导致订单服务在调用积分服务的时候,积分并没有增加,但是库存服务正确的接收到订单服务的请求,库存减少了。那么最终就会导致数据的不一致性。

JTA(XA)

当我们在单体应用中我们可以通过回滚的操作,来避免这种异常带来的数据不一致性,但是在分布式系统中,每个服务都有着自己的一套体系,有着自己的数据库,这就导致,我们没法控制其他的服务也能做到回滚。

XA是由X/Open组织提出的分布式事务规范

XA 只是一个规范,它要求采用两阶段方案(Pre、Commit)

JTA(Java Transaction API) J2EE模块,定义Java的XA接口

J2EE容器(Weblogic、JBoss)是JTA接口的具体实现者

基于这样的前提下,我们可以强行将所有的服务之间的业务交流,放在一个地方(J2EE容器中)进行统一管理,一旦有一个没有完成准备好就全部回滚。

image.png

JTA的问题

  • 同步阻塞,并发效率差

两阶段提交方式导致一条业务线,必须所有服务都准备好,再一起提交,这样就会造成系统卡顿,严重影响并发效率。

  • 分布式架构存在瓶颈

当我们将分布式事务依托与J2EE容器后,这个容器将会成为系统稳定的瓶颈,一旦这个容器出现故障,将会导致整个系统事务失效,所以我们还需要去考虑这个容器可用性。

  • 脑裂,无法保证数据一致性

所有服务准备好,当容器向各个服务commit后,在各自服务内,也有可能出现异常情况,这个时候,容器是无法感知到的,这样依然会造成数据不一致。

  • 数据源类型受限

JTA方案下,事务依赖于关系型数据库,数据的回滚,所以容器内的所有服务需要使用关系型数据库。