转载请注明来源-作者@loongshawn:http://blog.youkuaiyun.com/loongshawn/article/details/52164730
1、介绍
开发中有时候会碰到使用多个数据源的情况,这种情况也分两种不同的业务场景:
(1)、多个数据源是各自独立的,可以把它当作不同的项目来开发。比如一个是业务1的数据库,另一个是业务2的数据库。
(2)、多个数据源之间是主从关系(master-slave),其中一个数据库是master库,另外几个是slave库,从库需要同步主库的更新及变化。
2、背景
当前我的业务是在同一个工程中,接入另外一个数据库,提供计算与API服务,与当前工程所使用的库没有关联,两个数据库独立,所以我只需要针对上述场景(1)调整配置即可。
3、配置
3.1、修改application-dev.properties文件
修改application-dev.properties文件,新增数据库配置地址及权限。
单一库时的配置:
# mysql第一数据源
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_2
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.initialSize=10
spring.datasource.maxActive=99
spring.datasource.maxIdle=20
spring.datasource.minIdle=9
spring.datasource.removeAbandoned=true
spring.datasource.removeAbandonedTimeout=180
spring.datasource.maxWait=60000
spring.datasource.validationQuery=select 1 from dual
spring.datasource.testOnBorrow=true
spring.datasource.connectionProperties=clientEncoding=UTF-8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
新增一个库后的配置:
# mysql第一数据源
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_1
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.initialSize=10
spring.datasource.maxActive=99
spring.datasource.maxIdle=20
spring.datasource.minIdle=9
spring.datasource.removeAbandoned=true
spring.datasource.removeAbandonedTimeout=180
spring.datasource.maxWait=60000
spring.datasource.validationQuery=select 1 from dual
spring.datasource.testOnBorrow=true
spring.datasource.connectionProperties=clientEncoding=UTF-8
# mysql第二数据源
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_2
spring.datasource.username=test
spring.datasource.password=test
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
说明:第二个数据源中只需要修改数据库地址及权限即可,数据库的基本配置参数可与数据源一公用。
3.2、修改applicationContext.xml文件
原来单一数据源时的文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<bean id="properties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:spring/config/application-dev.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="${spring.datasource.driverClassName}" />
<property name="url" value="${spring.datasource.url}" />
<property name="username" value="${spring.datasource.username}" />
<property name="password" value="${spring.datasource.password}" />
<property name="initialSize" value="${spring.datasource.initialSize}" />
<property name="maxActive" value="${spring.datasource.maxActive}" />
<property name="maxIdle" value="${spring.datasource.maxIdle}" />
<property name="minIdle" value="${spring.datasource.minIdle}" />
<property name="removeAbandoned" value="${spring.datasource.removeAbandoned}" />
<property name="removeAbandonedTimeout" value="${spring.datasource.removeAbandonedTimeout}" />
<property name="maxWait" value="${spring.datasource.maxWait}" />
<property name="validationQuery" value="${spring.datasource.validationQuery}" />
<property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" />
<property name="connectionProperties" value="${spring.datasource.connectionProperties}" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:com/autonavi/dao/impl/mapper/*.xml" />
<property name="typeAliasesPackage" value="com.autonavi.domain" />
</bean>
<!-- mybatis.spring自动映射 -->
<bean id="mybatisMapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.autonavi.dao.impl.mapper" />
<!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />-->
</bean>
<bean id="springContextUtil" class="com.autonavi.utils.MyApplicationContextUtil"/>
<bean id="appErrorController" class="com.autonavi.controller.AppErrorController"/>
<!-- Enables the Spring Task @Scheduled programming model -->
<task:executor id="executor" pool-size="10" />
<task:scheduler id="scheduler" pool-size="20" />
<task:annotation-driven executor="executor" scheduler="scheduler" />
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthenticatedException">pages/403</prop>
<prop key="org.apache.shiro.authz.UnauthorizedException">pages/403</prop>
<prop key="org.apache.shiro.authc.LockedAccountException">pages/locked</prop>
<prop key="java.lang.Throwable">pages/500</prop>
</props>
</property>
</bean>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
新增数据源后的文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<bean id="properties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:spring/config/application-dev.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="${spring.datasource.driverClassName}" />
<property name="url" value="${spring.datasource.url}" />
<property name="username" value="${spring.datasource.username}" />
<property name="password" value="${spring.datasource.password}" />
<property name="initialSize" value="${spring.datasource.initialSize}" />
<property name="maxActive" value="${spring.datasource.maxActive}" />
<property name="maxIdle" value="${spring.datasource.maxIdle}" />
<property name="minIdle" value="${spring.datasource.minIdle}" />
<property name="removeAbandoned" value="${spring.datasource.removeAbandoned}" />
<property name="removeAbandonedTimeout" value="${spring.datasource.removeAbandonedTimeout}" />
<property name="maxWait" value="${spring.datasource.maxWait}" />
<property name="validationQuery" value="${spring.datasource.validationQuery}" />
<property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" />
<property name="connectionProperties" value="${spring.datasource.connectionProperties}" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:com/autonavi/dao/impl/mapper/*.xml" />
<property name="typeAliasesPackage" value="com.autonavi.domain" />
</bean>
<!-- mybatis.spring自动映射 -->
<bean id="mybatisMapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.autonavi.dao.impl.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- 第二个数据源配置 -->
<bean id="dataSource2" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="${spring.datasource.driverClassName}" />
<property name="url" value="${spring.datasource.url2}" />
<property name="username" value="${spring.datasource.username2}" />
<property name="password" value="${spring.datasource.password2}" />
<property name="initialSize" value="${spring.datasource.initialSize}" />
<property name="maxActive" value="${spring.datasource.maxActive}" />
<property name="maxIdle" value="${spring.datasource.maxIdle}" />
<property name="minIdle" value="${spring.datasource.minIdle}" />
<property name="removeAbandoned" value="${spring.datasource.removeAbandoned}" />
<property name="removeAbandonedTimeout" value="${spring.datasource.removeAbandonedTimeout}" />
<property name="maxWait" value="${spring.datasource.maxWait}" />
<property name="validationQuery" value="${spring.datasource.validationQuery}" />
<property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" />
<property name="connectionProperties" value="${spring.datasource.connectionProperties}" />
</bean>
<bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="mapperLocations" value="classpath*:com/autonavi/dao/impl/mapper2/*.xml" />
<property name="typeAliasesPackage" value="com.autonavi.domain" />
</bean>
<!-- mybatis.spring自动映射 -->
<bean id="mybatisMapperScanner2" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.autonavi.dao.impl.mapper2.pmp" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2" />
</bean>
<bean id="springContextUtil" class="com.autonavi.utils.MyApplicationContextUtil"/>
<bean id="appErrorController" class="com.autonavi.controller.AppErrorController"/>
<!-- Enables the Spring Task @Scheduled programming model -->
<task:executor id="executor" pool-size="10" />
<task:scheduler id="scheduler" pool-size="20" />
<task:annotation-driven executor="executor" scheduler="scheduler" />
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthenticatedException">pages/403</prop>
<prop key="org.apache.shiro.authz.UnauthorizedException">pages/403</prop>
<prop key="org.apache.shiro.authc.LockedAccountException">pages/locked</prop>
<prop key="java.lang.Throwable">pages/500</prop>
</props>
</property>
</bean>
</beans>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
其中新增的配置如下,同时大家需要注意以下几点:
- dataSource2、sqlSessionFactory2、mybatisMapperScanner2的名字改写,与数据源一不要一样。
- 在mybatisMapperScanner、mybatisMapperScanner2中添加属性sqlSessionFactoryBeanName,值为sqlSessionFactory、sqlSessionFactory2。
下面为新增的数据源配置:
<!-- 第二个数据源配置 -->
<bean id="dataSource2" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="${spring.datasource.driverClassName}" />
<property name="url" value="${spring.datasource.url2}" />
<property name="username" value="${spring.datasource.username2}" />
<property name="password" value="${spring.datasource.password2}" />
<property name="initialSize" value="${spring.datasource.initialSize}" />
<property name="maxActive" value="${spring.datasource.maxActive}" />
<property name="maxIdle" value="${spring.datasource.maxIdle}" />
<property name="minIdle" value="${spring.datasource.minIdle}" />
<property name="removeAbandoned" value="${spring.datasource.removeAbandoned}" />
<property name="removeAbandonedTimeout" value="${spring.datasource.removeAbandonedTimeout}" />
<property name="maxWait" value="${spring.datasource.maxWait}" />
<property name="validationQuery" value="${spring.datasource.validationQuery}" />
<property name="testOnBorrow" value="${spring.datasource.testOnBorrow}" />
<property name="connectionProperties" value="${spring.datasource.connectionProperties}" />
</bean>
<bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="mapperLocations" value="classpath*:com/autonavi/dao/impl/mapper2/*.xml" />
<property name="typeAliasesPackage" value="com.autonavi.domain" />
</bean>
<!-- mybatis.spring自动映射 -->
<bean id="mybatisMapperScanner2" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.autonavi.dao.impl.mapper2.pmp" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2" />
</bean>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
如上所示,我们分别配置了两个 dataSource,两个sqlSessionFactory,两个mybatisMapperScanner,以及关键的地方在于MapperScannerConfigurer 的配置——使用sqlSessionFactoryBeanName属性,注入不同的sqlSessionFactory的名称,这样的话,就为不同的数据库对应的 mapper 接口注入了对应的 sqlSessionFactory。
4、测试
4.1、测试要求
工程运行后,可同时连接2个数据库进行相关业务操作。
4.2、新建测试用例
新建测试类QuarterTest,其中quarterMapper来自数据源一,projectMapper来自数据源二:
public class QuarterTest {
private static final Logger logger = LoggerFactory.getLogger(QuarterTest.class);
@Autowired
private QuarterMapper quarterMapper;
public void action(){
// no.1 初始化工作
quarterMapper = MyApplicationContextUtil.getBean("quarterMapper");
ProjectMapper projectMapper = MyApplicationContextUtil.getBean("projectMapper");
List<Version> list1 = quarterMapper.selectQuarters();
List<Version> list2 = projectMapper.selectQuarters();
logger.info("数据源1,size:{}",list1.size());
for(Version quarter : list1){
logger.info("QuarterTest.method [action]: info id:{},version_name:{},year:{},fiscal_year:{}", quarter.getId(),quarter.getVersion_name(),quarter.getYear(),quarter.getFiscal_year());
}
logger.info("数据源2,size:{}",list2.size());
for(Version quarter : list2){
logger.info("QuarterTest.method [action]: info id:{},version_name:{},year:{},fiscal_year:{}", quarter.getId(),quarter.getVersion_name(),quarter.getYear(),quarter.getFiscal_year());
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
4.3、测试结果
(1)工程运行正常
(2)任务执行结果
第一个数据源查询结果为45条记录:
第二个数据源查询结果为29条记录:
Console输出结果:
2016-08-09-14-22 [scheduler-3] [com.autonavi.task.ScheduledTasks] [INFO] - ScheduledTest.executeFileDownLoadTask 定时任务1:17,name:scheduler-3
2016-08-09-14-22 [scheduler-2] [java.sql.Connection] [DEBUG] - ooo Using Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@56b5dd08]]]
2016-08-09-14-22 [scheduler-2] [java.sql.Connection] [DEBUG] - ==> Preparing: SELECT id, version_name, year, fiscal_year FROM version_table
2016-08-09-14-22 [scheduler-2] [java.sql.PreparedStatement] [DEBUG] - ==> Parameters:
2016-08-09-14-22 [scheduler-2] [java.sql.Connection] [DEBUG] - ooo Using Connection [ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@65e921a2]]]
2016-08-09-14-22 [scheduler-2] [java.sql.Connection] [DEBUG] - ==> Preparing: SELECT id, version_name, year, fiscal_year FROM version_table
2016-08-09-14-22 [scheduler-2] [java.sql.PreparedStatement] [DEBUG] - ==> Parameters:
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - 数据源1,size:45
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:1,version_name:2016Q1,year:2016,fiscal_year:2015
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:2,version_name:2016Q2,year:2016,fiscal_year:2016
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:3,version_name:2016Q3,year:2016,fiscal_year:2016
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:4,version_name:2016Q4,year:2016,fiscal_year:2016
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:5,version_name:2017Q1,year:2017,fiscal_year:2016
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:6,version_name:2017Q2,year:2017,fiscal_year:2017
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:7,version_name:2017Q3,year:2017,fiscal_year:2017
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:8,version_name:2017Q4,year:2017,fiscal_year:2017
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:9,version_name:2018Q1,year:2018,fiscal_year:2017
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:10,version_name:2018Q2,year:2018,fiscal_year:2018
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:11,version_name:2018Q3,year:2018,fiscal_year:2018
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:12,version_name:2018Q4,year:2018,fiscal_year:2018
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:13,version_name:2019Q1,year:2019,fiscal_year:2018
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:14,version_name:2019Q2,year:2019,fiscal_year:2019
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:15,version_name:2019Q3,year:2019,fiscal_year:2019
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:16,version_name:2019Q4,year:2019,fiscal_year:2019
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:17,version_name:2020Q1,year:2020,fiscal_year:2019
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:18,version_name:2020Q2,year:2020,fiscal_year:2020
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:19,version_name:2020Q3,year:2020,fiscal_year:2020
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:20,version_name:2020Q4,year:2020,fiscal_year:2020
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:21,version_name:2021Q1,year:2021,fiscal_year:2020
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:22,version_name:2021Q2,year:2021,fiscal_year:2021
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:23,version_name:2021Q3,year:2021,fiscal_year:2021
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:24,version_name:2021Q4,year:2021,fiscal_year:2021
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:25,version_name:2022Q1,year:2022,fiscal_year:2021
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:26,version_name:2022Q2,year:2022,fiscal_year:2022
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:27,version_name:2022Q3,year:2022,fiscal_year:2022
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:28,version_name:2022Q4,year:2022,fiscal_year:2022
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:29,version_name:2023Q1,year:2023,fiscal_year:2022
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:30,version_name:2023Q2,year:2023,fiscal_year:2023
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:31,version_name:2023Q3,year:2023,fiscal_year:2023
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:32,version_name:2023Q4,year:2023,fiscal_year:2023
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:33,version_name:2024Q1,year:2024,fiscal_year:2023
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:34,version_name:2024Q2,year:2024,fiscal_year:2024
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:35,version_name:2024Q3,year:2024,fiscal_year:2024
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:36,version_name:2024Q4,year:2024,fiscal_year:2024
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:37,version_name:2025Q1,year:2025,fiscal_year:2024
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:38,version_name:2025Q2,year:2025,fiscal_year:2025
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:39,version_name:2025Q3,year:2025,fiscal_year:2025
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:40,version_name:2025Q4,year:2025,fiscal_year:2025
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:41,version_name:2026Q1,year:2026,fiscal_year:2025
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:42,version_name:2026Q2,year:2026,fiscal_year:2026
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:43,version_name:2026Q3,year:2026,fiscal_year:2026
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:44,version_name:2026Q4,year:2026,fiscal_year:2026
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:45,version_name:2027Q1,year:2027,fiscal_year:2026
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - 数据源2,size:29
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:1,version_name:2016Q1,year:2016,fiscal_year:2015
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:2,version_name:2016Q2,year:2016,fiscal_year:2016
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:3,version_name:2016Q3,year:2016,fiscal_year:2016
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:4,version_name:2016Q4,year:2016,fiscal_year:2016
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:5,version_name:2017Q1,year:2017,fiscal_year:2016
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:6,version_name:2017Q2,year:2017,fiscal_year:2017
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:7,version_name:2017Q3,year:2017,fiscal_year:2017
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:8,version_name:2017Q4,year:2017,fiscal_year:2017
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:9,version_name:2018Q1,year:2018,fiscal_year:2017
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:10,version_name:2018Q2,year:2018,fiscal_year:2018
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:11,version_name:2018Q3,year:2018,fiscal_year:2018
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:12,version_name:2018Q4,year:2018,fiscal_year:2018
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:13,version_name:2019Q1,year:2019,fiscal_year:2018
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:14,version_name:2019Q2,year:2019,fiscal_year:2019
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:15,version_name:2019Q3,year:2019,fiscal_year:2019
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:16,version_name:2019Q4,year:2019,fiscal_year:2019
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:17,version_name:2020Q1,year:2020,fiscal_year:2019
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:18,version_name:2020Q2,year:2020,fiscal_year:2020
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:19,version_name:2020Q3,year:2020,fiscal_year:2020
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:20,version_name:2020Q4,year:2020,fiscal_year:2020
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:21,version_name:2021Q1,year:2021,fiscal_year:2020
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:22,version_name:2021Q2,year:2021,fiscal_year:2021
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:23,version_name:2021Q3,year:2021,fiscal_year:2021
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:24,version_name:2021Q4,year:2021,fiscal_year:2021
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:25,version_name:2022Q1,year:2022,fiscal_year:2021
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:26,version_name:2022Q2,year:2022,fiscal_year:2022
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:27,version_name:2022Q3,year:2022,fiscal_year:2022
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:28,version_name:2022Q4,year:2022,fiscal_year:2022
2016-08-09-14-22 [scheduler-2] [com.autonavi.method.pmp.QuarterTest] [INFO] - QuarterTest.method [action]: info id:29,version_name:2023Q1,year:2023,fiscal_year:2022
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
5、总结
上面的这种多数据源配置是不支持分布式事务的,也就是同一个事务中,不能操作多个数据库。这种配置方式的优点是很简单,但是却不灵活,需要依据业务场景来选择,如我当前的业务场景通过上述配置即可快速达成要求。
对于master-slave类型的多数据源配置而言不太适应,master-slave性的多数据源的配置,需要特别灵活,需要根据业务的类型进行细致的配置。比如对于一些耗时特别大的select语句,我们希望放到slave上执行,而对于update,delete等操作肯定是只能在master上执行的,另外对于一些实时性要求很高的select语句,我们也可能需要放到master上执行——比如一个场景是打游戏过程中,去商城购买一件兵器,购买操作的很定是master,同时购买完成之后,需要重新查询出我所拥有的兵器和金币,那么这个查询可能也需要防止master上执行,而不能放在slave上去执行,因为slave上可能存在延时,我们可不希望玩家发现购买成功之后,在背包中却找不到兵器的情况出现。
至于如何解决这种场景下的多数据库源配置,还有待继续学习。在此我整理了部分网络上的解决方案:
对于master-slave类型的多数据源的配置,需要根据业务来进行灵活的配置,哪些select可以放到slave上,哪些select不能放到slave上。所以上面的那种所数据源的配置就不太适应了,需要采用另外一套方式。即,利用基于 AbstractRoutingDataSource 和 AOP 的多数据源的配置。
其基本原理是,自己定义一个DataSource类ThreadLocalRountingDataSource,来继承AbstractRoutingDataSource,然后在配置文件中向ThreadLocalRountingDataSource注入 master 和 slave 的数据源,然后通过 AOP 来灵活配置,在哪些地方选择 master 数据源,在哪些地方需要选择 slave数据源。具体实现将会在后续文章中说明。