### 说明 - 程序主要是通过`/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_process`和`saas_biz`两个数据源, 如果执行业务单据审核方法失败了,那么就需要回滚`saas_biz`的事务,同时也要回滚`saas_process`的 事务;如果审核方法执行成功了,那么就是提交`saas_biz`事务,同时提交`saas_process`事务。也就是说, 多个事务的提交与回滚应该是原子性的。 程序里面使用`atomikos`和`MysqlXADataSource`来实现分布式事务。具体使用与一般的事务一样,在方法上面加 `@Transactional`注解即可。方法里面涉及的每个数据源连接都会自动创建子事务,方法正常执行完成后,会一起提交。 需要注意的是,开启了分布式事务,则存储过程里面不能开启独立事务,否则会破坏事务一致性。