记一次使用Atomikos + mycat遇到的问题

项目场景描述:

原A服务系统架构为springboot + sharding jdbc + Atomikos(多数据源),sharding jdbc主要为了A服务的分表处理,Atomikos主要为了处理分布式事务问题,因为在A服务中集成了对B服务库的操作(A服务与B服务是不同语言的服务)。

现在B服务的b1单表数据量过于庞大,已经远远不能满足现在的业务需求,需要进行分库分表处理。B服务现在准备采用mycat进行分库操作,对于A服务,因为以前内部集成了一些B服务的b1表一些操作,所以也需跟着变更。

搭建使用过程:

在java A服务中集成了mycat中间件进来,由于A服务之前就已经有两个不同实例的数据源存在,现在需要添加第三个数据源进行对mycat的操作。

关于mycat数据源的配置,主要是连接mycat的服务

关于mycat server端可以采用jar形式放在服务器上启动,也可以下载mycat源码本地启动,我采用的是后者。

关于mycat的分片规则,采用的是十进制求摸分片;启动mycat server服务后,insert 插入两条数据,再通过select 查询结果,达到了我们想要的效果,确实进行了分片。

A服务现在只需要对B服务的进行查询,不需要进行insert/update/delete操作, 所以上面的操作已经满足了当前的业务需求,从mycat官网上看,从1.6.5版本以上,mycat支持了弱XA。通过测试后,发现确实支持了跨库的分布式事务处理。

什么是弱XA?

Mycat 目前没有出来跨分片的事务强一致性支持,目前单库内部可以保证事务的完整性,如果跨库事务,在执行的时候任何分片出错,可以保证所有分片回滚,但是一旦应用发起 commit 指令,无法保证所有分片都成功,考虑到某个分片挂的可能性不大所以称为弱 xa。

问题描述:

现在A服务里面有2个数据源,A服务里面集成了spring-boot-starter-jta-atomikos进行XA事务处理。如果A服务已经集成了关于XA事务的处理,mycat里面自带的弱XA事务,如果现在假设有一个场景,A服务多数据源进行操作,对于A数据insert/update之后,再调用mycat数据源进行一个update操作,假如mycat update 操作之后报错,会不会进行全部回滚。

1、在一个服务中,如果没有集成了XA事务,那么在执行过程中,到mycat server端会进入DruidMycatRouteStrategy类中的routeNormalSqlWithAST()方法,执行到解析SQL语法的时候,正常的insert如下图所示:

通过mycat server端日志可以看出,执行了对应的库进行了insert 操作,查看数据库后发现确实执行成功

2、但对于一个集成了XA事务后,mycat服务的事务管理不交给xa事务管理,比如上面的那个xaTransaction()方法,该方法执行到了myCat操作的那个方法时候,首先会通过A服务中的mycat连接到mycat server端,进行SQL解析路由等操作;最终的结果可想而知,xaTransaction()方法的两个方法操作进行了回滚,但是关于mycat操作的数据并不能回滚。

3、那么是否可以把mycat服务的操作也交给XA事务执行管理呢?通过XA事务管理,如果程序报错需要事务回滚,那么XA帮忙进行全部回滚操作。通过配置mycat数据源的操作也交给XA事务管理,同样执行上面的xaTransaction()方法,在mycat server端 SQL解析的时候,报SQL解析错误,

4、关于XA RECOVERY,我的理解是这个是一个关于XA事务日志恢复的操作,而在mycat server端,SQL解析的时候不支持该种语法,所以会报解析错误。

结论:

一个项目中,如果配置了XA对与多个数据源进行管理,再把关于mycat数据源的操作也交给atomikosTransactionManager 进行管理,会出现SQL解析错误。对于这样的场景,一般的话最好是A服务直接去调用B服务的接口,直接交给B服务直接处理;关于事务这一层,可以考虑采用本地时间表或者消息形式进行事务的回滚操作。

你可能感兴趣的:(记一次使用Atomikos + mycat遇到的问题)