Guns第七节多数据源的配置和使用

时间:2024-03-23 21:55:47

Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用

大家可以看到两个数据源就是这两个方法,第一个方法是biz数据库对应的数据源bizDataSource,第二个方法是guns数据库对应的数据源,他们对应的方法都是通过properties文件,之前介绍springboot的时候已经介绍过了,他们这个properties运行原理是通过读取yml里面的这些值Guns第七节多数据源的配置和使用,然后注入到这个properties不同的属性里面Guns第七节多数据源的配置和使用

然后看一下它们是怎么配置的,怎么配置的就是通过这个config方法Guns第七节多数据源的配置和使用,这个config方法其实就是一系列的set,可以把spring初始化的这些值set到数据源里面。大家可以看到当用的时候,它会把这个datasource set进去Guns第七节多数据源的配置和使用properties这些值。大家可以看到这都是一系列的set方法Guns第七节多数据源的配置和使用。然后这样就配置了两个数据源。

Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用Guns第七节多数据源的配置和使用的意思就是决定当前使用哪个数据源。通过字面意思就是说他是一个路由datasource,执行当操作数据库的时候需要告诉它当前使用哪一个数据库,然后这个Guns第七节多数据源的配置和使用决定当前使用的哪个datasource。然后它是如何决定的?通过这个方法Guns第七节多数据源的配置和使用,决定当前的一个key,这个key就是在配置这个Guns第七节多数据源的配置和使用的时候注入的这个keyGuns第七节多数据源的配置和使用,下面大家可以看一下这个方法Guns第七节多数据源的配置和使用,这个方法是配置DynamicDataSource,大家可以看到这个方法里面首先初始化了这两个数据源

Guns第七节多数据源的配置和使用,初始化了之后,它又初始化了一个map,map的key就是数据源的标识Guns第七节多数据源的配置和使用,大家可以看到guns数据源的标识定义了这样一个常量Guns第七节多数据源的配置和使用,biz的数据源定义了另外一个常量,那么以这个常量作为key标识这个数据源,然后set了一个TargetDataSourceGuns第七节多数据源的配置和使用,就是设定了这个路由将会跳转的一个dataSource,就是当请求数据库的时候,会通过路由dataSource决定当前使用哪一个datasource,通过这个方法Guns第七节多数据源的配置和使用决定的。这个方法是如何决定使用哪个数据源呢?这里有一个Guns第七节多数据源的配置和使用,这个holder里面就是放的当前环境会使用哪一个数据源。Guns第七节多数据源的配置和使用这个类面大家可以看到,它用了一个ThreadLocal,ThreadLocal的意思就是为每一个线程创建一个副本,每一个线程里面的这一个变量的值都不会被其他线程影响。ThreaLocal这个变量来控制当前的dataSource是哪一个dataSource,然后设置这个dataSource的时候调用这个setGuns第七节多数据源的配置和使用,获取的时候通过getGuns第七节多数据源的配置和使用,然后清除Guns第七节多数据源的配置和使用

这个Guns第七节多数据源的配置和使用就是刚才定义的这个枚举里面的常量,Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用,默认的就是我们的guns数据源

Guns第七节多数据源的配置和使用Guns第七节多数据源的配置和使用,这里就相当于设定了一个开关,如果是false的话,就配置了一个单数据的数据源Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用。这个AOP的作用就是你在写service的时候决定你当前的service使用哪一个数据源,然后这个AOP是通过注解的方式来拦截的的,大家可以通过扫描包的方式,就是说直接配置一个包的路径Guns第七节多数据源的配置和使用,当service包的方法执行的时候Guns第七节多数据源的配置和使用,他会走这个逻辑(AOP)Guns第七节多数据源的配置和使用,这里是通过注解方式,当你标注了annotation的时候Guns第七节多数据源的配置和使用,这个AOPGuns第七节多数据源的配置和使用才会执行,拦截的是这个dataSourceGuns第七节多数据源的配置和使用

然后看一下这个aop的具体内容,Guns第七节多数据源的配置和使用

首先这个aop获取了当前方法执行的这个注解Guns第七节多数据源的配置和使用

Guns第七节多数据源的配置和使用

然后获取了这个注解的名称Guns第七节多数据源的配置和使用

这个注解里面就一个属性Guns第七节多数据源的配置和使用,这个name就是多数据源的名称,多数据源的名称就是枚举里面常量的名称,这个AOP首先获取到这个注解,获取当前方法的注解Guns第七节多数据源的配置和使用,如果注解不等于null,Guns第七节多数据源的配置和使用,如果当前有这个注解,就设置当前多数据源的名称。Guns第七节多数据源的配置和使用这里是一个切换,把它切换之后,这个DynamicDataSource才会起作用。他才会知道使用哪一个数据源Guns第七节多数据源的配置和使用,它才会知道当前应该使用哪一个数据源,然后如果这个注解它是空的话,就是默认使用guns的数据源

Guns第七节多数据源的配置和使用,数据源切换之后就会执行该方法Guns第七节多数据源的配置和使用,执行完之后,把当前数据源的名称清除掉。Guns第七节多数据源的配置和使用

多数据源跟事物的一个顺序,多数据源的一个切换一定要放在事物的AOP之前Guns第七节多数据源的配置和使用

一定要早于AOP的事物,这样多数据源的切换才能生效,所以说这里有一个order,这需要设置顺序,同样地也需要设置spring事物的顺序,spring事物的顺序在这里设置的

Guns第七节多数据源的配置和使用,事物要放在AOP之后,要不然事物它会不生效。

Guns第七节多数据源的配置和使用

下面做一个演示,比如说测试一下biz数据源,这边写了一个测试用例

Guns第七节多数据源的配置和使用,比如说测试一下bizGuns第七节多数据源的配置和使用,这条记录就是读取id为1的这条记录,然后把它的id设成22,然后重新插入到数据库Guns第七节多数据源的配置和使用

当前的biz表里面有一条数据Guns第七节多数据源的配置和使用,执行一个测试Guns第七节多数据源的配置和使用,刷新一下,大家可以看到又多了一条数据,Guns第七节多数据源的配置和使用,说明这个biz这个数据源生效了。

然后再测试一下gunsGuns第七节多数据源的配置和使用Guns第七节多数据源的配置和使用这个guns重新读取一条,然后再插入,执行成功后 就多了一条记录Guns第七节多数据源的配置和使用。这个记录跟预期的可能不太一样,因为这个业务本身意思是这样的,读取id为1的这条记录,然后把id设成33,然后再插入,然而这里是2Guns第七节多数据源的配置和使用,因为这里语句执行时这样的Guns第七节多数据源的配置和使用,因为我这个数据库的配置,Guns第七节多数据源的配置和使用Guns第七节多数据源的配置和使用,自增的话,他就不会写这个id了,不会写insert into test ('id')values(?).直接从id下边这个字段开始插入的。

然后再看一下这个TestAllGuns第七节多数据源的配置和使用,这里面分别调用了Guns第七节多数据源的配置和使用,两条同时执行看会不会生效,然后把他们都删掉先。执行后可以看到这两个插入命令都生效了,

如果这个两个多数据源同时调用的话,他必须是在两个不同的事务内,现在guns系统还没有做到两个数据源的操作在一个事务内完成,因为这需要引入一个分布式事务的框架,这个还没有引入,集成,所以大家在两个数据源在一个方法内操作的话,尽量避免同时写入,或者同时修改的操作,尽量是一个是读取,一个是操作。Guns第七节多数据源的配置和使用因为现在的情况是假如说,一个在失败的时候Guns第七节多数据源的配置和使用,这个Guns第七节多数据源的配置和使用是无法回滚的。这个Guns第七节多数据源的配置和使用可以回滚,而这个Guns第七节多数据源的配置和使用是无法回滚的。还有一点需要注意这个TestAll在调用的时候Guns第七节多数据源的配置和使用,假如说这个两个数据源,它这里不需要写事务。如果这里Guns第七节多数据源的配置和使用写Transactional的话,这里的操作是读取一个数据源的,读取默认的是guns的,如果这里Guns第七节多数据源的配置和使用是一个共同调度的方法,它就不要加事务。在这个Guns第七节多数据源的配置和使用里面各自加上事务。

后面会出一个分布式事务的解决方案。再把事务完善一下。