章节归属
分布式事务系列
概述
Seata的核心价值在于 构建一个全面解决分布式事务问题的标准化平台。
当前技术背景下,不存在一个分布式事务处理机制可以完美满足所有场景的需求,系统存在一致性、可靠性、易用性、性能等诸多方面的约束,需要不同的事务处理机制去满足。
基于Seata,上层应用架构可以根据实际场景的需求,灵活选择合适的分布式事务解决方案。
1.TCC模式(2PC、补偿型)
据说蚂蚁早期大量采用的分布式事务方案就是TCC模式,属于万金油了。
1.1 优点
资源锁定时间短
使用TCC模式时,在try阶段就提交了本地事务,并不会锁定资源,所以没有其他额外的性能开销
并发度高
可由其他方式锁定资源,而不必对数据加全局锁,允许多个事务同时操作数据。
应对场景多
- 可在非JDBC方式通信的DB(如Elasticsearch 、Redis)场景使用。
- 可在非DB场景(如三方rest接口)场景使用。
1.2 缺点
业务侵入严重
服务提供方必须已手动方式 将业务逻辑拆分成2阶段,实现try、confirm和cancel 3个方法,遵守分布式事务所约束的额外的规则。
开发维护成本高
try、confirm和cancel 3个固定逻辑,无法通过事务框架自动生成,设计、开发成本高,后续维护改造的成本也高。
2.AT模式(2PC、补偿型)
Seata中默认推荐的模式,官宣能应对当下80%的分布式场景。
2.1.优点:
业务无侵入
对业务无入侵,开发者只需正向关注自己的业务逻辑sql(与TCC模式比较,不需要将业务拆分并提供try、confirm、cancel方法),快速集成后即使用。
性能尚可
AT解析,一阶段提前释放本地锁,二阶段决议提交时释放全局锁,无需将数据锁定持续到二阶段结束,这里就已经相对传统二阶段事务尤其是XA提升了,TCC 、XA 都需要二阶段驱动,而AT模式在二阶段决议提交时分布式事务就已经完成了,无需再次驱动rm进行二阶段动作。
一阶段多了几次DB读写操作,有一定的性能损耗。
2.2.缺点:
存在中间状态
补偿型事务处理机制构建在事务资源之上(在中间件或者应用层,而不是DB层),事务资源本身对分布式事务无感知,这就导致无法做到全方位隔离,即中间状态可见。在Seata中,要通过应用层的锁机制来达到读已提交的隔离效果。
依赖全局行锁
AT需要全局行锁来保证隔离性,所以无论是单库的操作还是1-n个服务都需要开启全局事务来保证隔离性。
有一定的适配成本
支持mysql,pgsql,oracle等数据库,需要应用层做适配,对复杂sql的解析成本更大,开发效率低,支持的sql数量少;跨语言的需要在应用层额外的开发支持。但一旦是社区已经提供好的则无需考虑这些问题。
3.Seata XA模式(2PC、强一致)
DTP定义TM和RM之间采用XA接口通讯协议,XA模式就是基于数据库的XA协议来实现的两阶段提交方案。
3.1.优点:
全局一致性
AT模式下数据的读已提交需由额外的应用层的全局行锁机制来保障;而 XA模式下,隔离性由数据库自身保障,资源和全局事务浑然一体,做到全局一致性
侵入性略低
少于2个服务的操作,XA仅使用本地事务即可满足一致性,不再需要TC的参与。
兼容性好
- XA协议被主流的db(mysql,pgsql,oracle)支持,没有sql语法的限制,而AT需要由应用层额外的代码来解析并适配sql.
- XA是协议层的,多语言支持度高。
3.2.缺点:
锁粒度大
XA本地数据库可能持有间隙锁,造成锁的粒度更大,锁定更多无辜数据
死锁(协议阻塞)
准备阶段后,各分支事务进入阻塞阶段,收到 提交\回滚的指令之前必须阻塞等待。而这期间如果有什么异常导致TM无法下达提交\回滚的指令,那么这个没有提交的xa事务将会一直 持有锁,造成死锁的局面。
性能较差
据说使用XA分布式事务跟没有事务的情况下有10倍的性能差异,主要原因就是上面的阻塞跟数据锁定造成,因为xa的一阶段并非提交,带来以下2个问题:
- 事务协调过程,增加单个事务的 RT;
- 并发事务数据的锁冲突,降低吞吐。
应用场景受限
- 适用于单体应用多数据源的情况(早期大型机上的金融类单体应用用的多)
- 不适用于分布式场景
At模式的一阶段提交,AT的性能是优于XA,因为它锁在TC一侧集中释放,无需多个库进行本地的锁释放
运维成本
在mysql数据库中对XA支持的不太理想,mysql的XA实现,没有记录prepare阶段日志,主备切换回导致主库与备库数据不一致(这些是不是MySQL 5.7之前的缺陷,mysql8之后的情况怎样呢?)运维复杂,DBA缺少这方面经验;
这段信息有待确认