动态数据源、多数据中心与分布式事务.md 2.5 KB

说明

  • 程序主要是通过/base/base-datacenter/base-datacenter-client模块来实现动态数据源、多数据中心的。

  • 为什么使用多个数据中心?

主要是为了减少单个数据中心的压力。每个公司在注册的时候,会按资源使用情况分配到不同的数据中心。

  • 为什么数据中心下有多个数据库?

目前是按业务拆分了不同数据库,例如账户管理使用的是saas_account数据库,流程管理使用的是saas_process数据库。

实现

数据源

SAAS服务端的启动数据库是saas_manage,表saas_manage.datacenter记录了全部数据中心, 表saas_manage.datasource记录了不同数据中心下的数据源参数。 表saas_account.ac_company记录了每个公司使用的数据中心。

标记需要使用的数据源

程序提供了@Database注解,用于在包、类或方法上标注该程序需要使用的数据源名称, 例如@Database("saas_biz")表示该方法使用的数据源是saas_biz。当然也可以直接在模块的 src/main/resources/application.properties文件里面配置database=xxx。 配置的优先级是 方法 > 类 > 包 > application.properties

动态切换

通过AOP,在所有需要用到数据源的方法执行前,会检查该方法配置的数据库名+当前登录用户使用的数据中心, 然后切换到该数据源(如果不存在数据源则自动创建),执行完再切换回来。 代码在com.usoftchina.saas.dc.client.aspect.DatabaseAspect.aroundExecution

分布式事务

处理某个业务时,可能涉及到多个应用,每个应用用到的数据源有可能不一样。 例如审批流程结束的同时要执行业务单据的审核方法,这里需要用到saas_processsaas_biz两个数据源, 如果执行业务单据审核方法失败了,那么就需要回滚saas_biz的事务,同时也要回滚saas_process的 事务;如果审核方法执行成功了,那么就是提交saas_biz事务,同时提交saas_process事务。也就是说, 多个事务的提交与回滚应该是原子性的。

程序里面使用atomikosMysqlXADataSource来实现分布式事务。具体使用与一般的事务一样,在方法上面加 @Transactional注解即可。方法里面涉及的每个数据源连接都会自动创建子事务,方法正常执行完成后,会一起提交。

需要注意的是,开启了分布式事务,则存储过程里面不能开启独立事务,否则会破坏事务一致性。