分布式事务
本框架原生分布式多数据源事务支持,无需依赖任何外部事务协调管理器或特别的服务支持。分布式事务管理模块基于TX-LCN重构,目前支持TCC、LCN(原生回滚)和TXC(补偿回滚)三种事务模型。 下面就这三种事务模型进行讲解说明。
#
配置首先我们配置好数据源,这里继续引用前面示例中使用的test数据库。下面配置了2个数据源,一个main主数据源,一个txlog数据源给事务日志使用。
test数据库中的demo表和演示数据sql文件在examples\quickstart示例包中的resources文件夹,也可以从数据库基础应用-演示数据复制。 上面配置中,jdbcIpFinder是节点发现设置,请看节点发现-JDBC发现,需要注意txLogger事务日志不可以和业务用同一个数据源,但可以是同一个数据库。
#
服务定义下面定义了一组对demo表进行查询和更新的数据库操作服务。
#
LCN事务模型LCN事务模型来源于TX-LCN,属于两阶段事务,也是本框架的默认事务模型,该事务模型有以下特点:
- LCN的主要优点有
- 该模式对代码零侵入。
- 该模式下的事务提交与回滚是由本地事务方控制,对于数据一致性上有较高的保障。
- LCN的主要缺点有
- 该模式仅限于本地存在连接对象且可通过连接对象控制事务的模块。
- 该模式缺陷在于代理的连接需要随事务发起方一起释放连接,增加了连接占用的时间。
下面的实例演示最基本的事务,并作为API提供给其他微服务,用于后面展示各种事务嵌套:
注意上面的@Transactional注解,默认事务模型是LCN,定义一个Controller来测试上面的事务,并导出API
下面的实例展示了LCN事务嵌套,以及需要留意的嵌套死锁场景:
最后定义Controller导出上面的服务:
通过浏览器即可测试上面的几种事务场景。
#
TCC事务模型TCC属于两阶段补偿型事务模型。TCC(Try-Confirm-Cancel)的概念,最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。 TCC事务机制相对于二阶段提交,其特征在于它不依赖资源管理器(RM)对XA协议的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务, 将事务分成 Try 和 Confirm/Cancel 两个阶段和三种操作: Try 尝试执行业务、 Confirm 确认执行业务、 Cancel 取消执行业务。 该事务模型有以下特点:
- TCC的主要优点有
- 该模式对有无本地事务控制都可以支持使用面广。
- 因为Try阶段检查并预留了资源,所以confirm阶段一般都可以执行成功。
- 资源锁定都是在业务代码中完成,不会block住DB,可以做到对db性能无影响。
- TCC的实时性较高,所有的DB写操作都集中在confirm中,写操作的结果实时返回。
- TCC的主要缺点有
- 因为事务状态管理,将产生多次DB操作,这将损耗一定的性能,并使得整个TCC事务时间拉长。
- 该模式对代码的嵌入性高,要求每个业务需要写三种步骤的操作。
- 事务涉及方越多,Try、Confirm、Cancel中的代码就越复杂,可复用性就越底。另外涉及方越多,这几个阶段的处理时间越长,失败的可能性也越高。
- 数据一致性控制几乎完全由开发者控制,对业务开发难度要求高。
下面的实例演示了基本的TCC事务,并嵌套调用了上面的LCN事务:
最后定义Controller导出上面的服务:
通过浏览器即可测试上面的TCC事务场景。
#
TXC事务模型TXC事务模型来源于阿里,也属于两阶段事务,该事务模型有以下特点:
- TXC的主要优点有
- 该模式同LCN一样,对代码零侵入。
- 该模式不会占用数据库的连接资源。
- TXC的主要缺点有
- 该模式仅限于对支持SQL方式的模块支持。
- 该模式由于每次执行SQL之前需要先查询并保存受影响的数据快照,因此相比LCN模式消耗资源与时间要多。
下面的实例演示了基本的TXC事务,并嵌套调用了上面的LCN事务:
最后定义Controller导出上面的服务:
通过浏览器即可测试上面的TXC事务场景。
#
SAGA事务模型暂不支持SAGA事务模型,后续根据需要确定是否增加对该事务模型的支持。
#
注意与建议注意
在一个事务中,需要留意所调用的微服务及子事务是否有对相同内容的修改动作,事务与子事务是否具有兼容合并条件,如果没有那么就要考虑修改内容是否涉及事务冲突。
强烈建议远程微服务嵌套层次越少越好,层次嵌套会大幅度降低性能(http请求嵌套),增加逻辑关系复杂度,而且后续开发容易忘记嵌套了多少层了。 最关键是还会导致事务嵌套关系复杂且难以管理,尤其是不同事务类型的嵌套。 嵌套限制在2层内,即只做1次远程调用效果最好,既能发挥分布式微服务的优点,又具有较低的业务逻辑关系和事务关系复杂度。