[TOC]
笔者水平有限,如有理解错误,欢迎勘误。
阅读本文前建议先阅读下列关于分布式事务理论基础的系列博文,此系列博文是笔记迄今阅读到的内容最考究,叙述最深入浅出的技术博客: 田守枝Java技术博客之分布式事务
ByteJTA现状
由于ByteJTA的repo里几乎没有说明文档,技术社区也没有相关博文,故与作者进行了一些交流。
与作者交流原话:
byteJTA还在维护呢,不过由于大环境对XA/2PC谈虎色变,所以byteJTA目前优先级排在byteTCC之后。有bug肯定会改,后续还计划有一次大的优化升级呢。
ByteJTA源码包结构
javax.transaction.xa
为Java对XA/JTA协议的支持包,其主要包括:
javax.transaction.Status:事务状态,这个接口主要是定义一些表示事务状态的常量,此接口无需实现
javax.transaction.Synchronization:同步
javax.transaction.Transaction:事务
javax.transaction.TransactionManager:事务管理器
javax.transaction.UserTransaction:用于声明一个分布式事务
javax.transaction.TransactionSynchronizationRegistry:事务同步注册
javax.transaction.xa.XAResource:定义RM提供给TM操作的接口
javax.transaction.xa.Xid:事务id
复制代码
由于ByteJTA是对XA/JTA 规范的实现,所以基于此包接口进行开发,以下为ByteJTA的包结构:
├─bytejta-core 对JTA规范的拓展实现
│ └─src
│ └─main
│ └─java
│ └─org
│ └─bytesoft
│ ├─bytejta transaction包下拓展的各个接口进行具体实现
│ │ ├─logging
│ │ │ ├─deserializer
│ │ │ └─store
│ │ ├─resource
│ │ ├─strategy
│ │ ├─supports
│ │ │ ├─jdbc
│ │ │ └─resource
│ │ ├─work
│ │ └─xa
│ ├─common 工具类
│ │ └─utils
│ └─transaction 对JTA规范接口进行拓展
│ ├─adapter
│ ├─archive
│ ├─aware set注入标志接口
│ ├─cmd Runable、Callable类型任务导航
│ ├─internal TransactionResource、TransactionListener缓存、同步控制
│ ├─logging 日志支持
│ │ └─store
│ ├─recovery
│ ├─remote 远程节点代表
│ ├─resource
│ ├─supports
│ │ ├─resource 扩展XAResource接口
│ │ ├─rpc RPC请求回应接口、拦截器接口
│ │ └─serialize 序列化、反序列化接口
│ ├─work Runable task包装
│ └─xa TransactionID拓展接口
├─bytejta-supports 对transaction包下拓展的各个接口进行具体实现
│ └─src
│ └─main
│ ├─java
│ │ └─org
│ │ └─bytesoft
│ │ └─bytejta
│ │ └─supports
│ │ ├─boot
│ │ │ └─jdbc
│ │ ├─internal
│ │ ├─jdbc
│ │ ├─jpa
│ │ │ └─hibernate
│ │ ├─resource
│ │ │ ├─jdbc
│ │ │ └─properties
│ │ ├─rpc
│ │ ├─serialize
│ │ └─spring
│ └─resources
├─bytejta-supports-dubbo dubbo对ByteJTA的通信支持
│ └─src
│ └─main
│ ├─java
│ │ └─org
│ │ └─bytesoft
│ │ └─bytejta
│ │ └─supports
│ │ └─dubbo
│ │ ├─config
│ │ ├─ext
│ │ ├─internal
│ │ ├─serialize
│ │ └─spi
│ └─resources
│ └─META-INF
│ └─dubbo
└─bytejta-supports-springcloud SpringCloud对ByteJTA的通信支持
└─src
└─main
├─java
│ └─org
│ └─bytesoft
│ └─bytejta
│ └─supports
│ └─springcloud
│ ├─config
│ ├─controller transaction coordinator直接通过http协议暴露接口
│ ├─dbcp
│ ├─feign
│ ├─hystrix
│ ├─loadbalancer
│ ├─property
│ ├─rule
│ ├─serialize
│ └─web
└─resources
复制代码
说明:接口抽象都在
org.bytesoft.transaction
包中定义其XA/JTA
规范接口进行了拓展,org.bytesoft.jta
包下均为具体实现,另外bytejta-supports-dubbo
和bytejta-supports-springcloud
模块下均为通信支持。故上述目录着重说明接口定义。
ByteJTA对 XA/JTA协议的支持
Tips:以下涉及Spring或dubbo支持的只叙述Spring。
ByteJTA是对XA/JTA协议的完整实践,是一个标准的事务管理器(TM)。同时实现了事务协调器(TC)的集群管理(TC也分布在各个Application里,这一点与seata将TC抽成独立的server并计划做集群不同)。
持有远程TC的地址对象,以便通信:
public class RemoteCoordinatorRegistry {
static final RemoteCoordinatorRegistry instance = new RemoteCoordinatorRegistry();
/* host:port -> participant(url= host: port) */
private final Map<RemoteAddr, RemoteCoordinator> physicalMap = new ConcurrentHashMap<RemoteAddr, RemoteCoordinator>();
/* host:port -> host:application:port */
private final Map<RemoteAddr, RemoteNode> mappings = new ConcurrentHashMap<RemoteAddr, RemoteNode>();
/* application -> participant */
private final Map<String, RemoteCoordinator> clusterMap = new ConcurrentHashMap<String, RemoteCoordinator>();
/* invocation -> host:application:port */
private final Map<InvocationDef, RemoteNode> invocationMap = new ConcurrentHashMap<InvocationDef, RemoteNode>();
复制代码
具体Coordinator通信见org.bytesoft.bytejta.supports.springcloud.controller.TransactionCoordinatorController
及其依赖。
SpringCloudConfiguration
中委托了自定义TransactionManager
,故可以使用Spring的@Transactional
注解直接开启全局事务:
public PlatformTransactionManager annotationDrivenTransactionManager() {
org.springframework.transaction.jta.JtaTransactionManager jtaTransactionManager //
= new org.springframework.transaction.jta.JtaTransactionManager();
jtaTransactionManager.setTransactionManager(this.applicationContext.getBean(TransactionManager.class));
jtaTransactionManager.setUserTransaction(this.applicationContext.getBean(UserTransaction.class));
return jtaTransactionManager;
}
复制代码
具体事务控制见org.bytesoft.bytejta.TransactionManagerImpl
。
横向比较
通信
Seata
基于netty实现transaction coordinator
与各application
的transaction management
之间的通信,并且通信部分被纳入core部分实现。
ByteJTA
构件core、support部分不负责实现通信,但考虑到集成到springcloud、dubbo通信的难度及成本,作者在ByteJTA-supports-dubbo和ByteJTA-supports-springcloud部分进行了集成。
笔者认为,通用构件或者框架的底层通信依赖于业务开发框架的web通信协议(http等),似乎有点不妥,性能和稳定性一定会受到影响,至于影响是否在可接受范围,笔者并没有进行详细测试。
resource manager
ByteJTA
基于数据库提供的XA接口实现,直接使用XAResource
与数据库交互。从而实现多个数据库连接之间的事务管理。
seata 通过程序实现RM,不需要依赖数据库提供的XA实现。并且优化了XA的2PC第二阶段锁占用问题。
Transaction coordinator
ByteJTA
每个application均含有TC角色,并且通过RemoteCoordinatorRegistry
缓存其他TC的地址信息。并通过springmvc或者dubbo通信。
由于数据库行锁被数据库本身RM所管理,所以其TC只负责协调各TM进行全局事务各阶段控制。
seata
将TC抽成独立Server单独部署,各application向其注册TM,并接受其协调。目前是单例版本,官方计划Server实现集群。
由于使用自己实现的RM进行本地事务的数据库交互,全局事务行锁信息则交由TC进行缓存(存储锁定行的keyid)。但由于自己实现了RM,RM不管理数据库锁定,在全局事务对某条数据A锁定的情况下,其他本地事务或者直接数据库操作无法感知数据A锁定,可以直接修改数据A,此时若全局事务回滚会造成脏读问题(seata 介绍中说最后提交的时候有判断,有预警方案,当前数据和undo_log表的后镜像不一致的话,log删不掉,需要人工介入,但在代码了没找到相应的说明)。
规范践行
ByteJTA
完整地践行了XA/JTA规范。
seata
在规范基础上提出新想法,优化事务二阶段提交锁定问题。
原创不易,觉得不错就点个赞以示鼓励吧!