springmvc 定时器 多数据源

0.目的:测试网上多数据源切换代码靠不靠谱

1.先说需求:根据摄像头采集到的数据,做一些业务上的特定处理,但是,但是很重要,摄像采集数据不直接存在此数据库,需要定时的去外部DB去取数据,这就涉及到多数据源,和spring定时器

2.直接上代码了

   多数据源配置文件 (重要的代码已上色)

<!-- DataSource -->
	<bean id="dataSource1" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	<bean id="dataSource2" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver1}" />
		<property name="url" value="${jdbc.url1}" />
		<property name="username" value="${jdbc.username1}" />
		<property name="password" value="${jdbc.password1}" />
	</bean>
	<bean id="dataSource" class="com.ryuantech.mp.common.DynamicDataSource" >
	    <property name="targetDataSources">
	        <map key-type="java.lang.String">
	            <!--通过不同的key决定用哪个dataSource-->
	            <entry value-ref="dataSource1" key="dataSource1"></entry>
	            <entry value-ref="dataSource2" key="dataSource2"></entry>
	        </map>
	    </property>
	    <!--设置默认的dataSource-->
	    <property name="defaultTargetDataSource" ref="dataSource1">
	    </property>
	</bean>
	
	
	<!--sqlSessionFactory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="mapperLocations">
			<array>
				<value>classpath:sqlmap/**/*.xml</value>
			</array>
		</property>
		<property name="configLocation" value="classpath:mybatis-config.xml" />
		<property name="dataSource" ref="dataSource" />
	</bean>
	<!-- transactionManager -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<!-- enable transaction annotation support -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	<!-- spring thread pool executor -->           
    <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 线程池维护线程的最少数量 -->
        <property name="corePoolSize" value="100" />
        <!-- 允许的空闲时间 -->
        <property name="keepAliveSeconds" value="60" />
        <!-- 线程池维护线程的最大数量 -->
        <property name="maxPoolSize" value="2000" />
        <!-- 缓存队列 -->
        <property name="queueCapacity" value="50" />
        <!-- 对拒绝task的处理策略 -->
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
        </property>
    </bean>

  定时器配置文件

头问价下面的代码必要
xmlns:task="http://www.springframework.org/schema/task" 
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd



<!-- 定时器 -->
	<task:annotation-driven/>  
	<context:component-scan base-package="com.ryuantech.mp.task"></context:component-scan> 

  数据源切换类代码

public class DynamicDataSource extends AbstractRoutingDataSource {


    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    @Override
    protected Object determineCurrentLookupKey() {
        String dataSource = getDataSource();
        return dataSource;
    }

    /**
     * 设置数据源
     * 
     * @param dataSource
     */
    public static void setDataSource(String dataSource) {
    	System.out.println("设置数据源:"+dataSource);
        contextHolder.set(dataSource);
    }

    /**
     * 获取数据源
     * 
     * @return
     */
    public static String getDataSource() {
        String dataSource = contextHolder.get();
        System.out.println("获取数据源:"+dataSource);
        // 如果没有指定数据源,使用默认数据源
        if (null == dataSource) {
            DynamicDataSource.setDataSource("dataSource1");
        }
        return contextHolder.get();
    }

    /**
     * 清除数据源
     */
    public static void clearDataSource() {
        contextHolder.remove();
    }

}

  定时器(切换到他DB)测试类

@Component("task")
public class FaceTask {

	@Autowired
	private FacecaptureinfoOthersService otherService;

	@Autowired
	private FacecaptureinfoService faceService;

	@Scheduled(cron = "0/5 * * * * ? ") // 间隔5秒执行
	public void getFaceInfoFromOthers() throws InterruptedException {

		Facecaptureinfo info = new Facecaptureinfo();
		for (int i= 0;i<20;i++) {
			info.setDevid(1);
			info.setVisitorid(Integer.parseInt("2"+i));
			info.setTime(new Date());
			otherService.selectBySelectedFromOther(i);
		}
	}
}

  定时器(切换到他DB)测试类

@Service
public class FacecaptureinfoOthersServiceImpl implements FacecaptureinfoOthersService{

	@Autowired
	private FacecaptureinfoMapper faceMapper;

	@Override
	public List<Facecaptureinfo> selectBySelectedFromOther(int i) {
//		DynamicDataSource.setDataSource("dataSource2");
//		List<Facecaptureinfo> list = faceMapper.selectBySelectedFromOthers(record);
//		DynamicDataSource.setDataSource("dataSource1");
//		return list;
		List<Facecaptureinfo> list = new ArrayList<Facecaptureinfo>();
		SimpleDateFormat sdf = new SimpleDateFormat("YYYY/MM/dd HH:mm:ss.SSS");
		
		System.out.println("selectBySelectedFromOther:开始");
		System.out.println("selectBySelectedFromOther:开始时间"+sdf.format(new Date()));
		DynamicDataSource.setDataSource("dataSource2");
		System.out.println("selectBySelectedFromOther:" + i);
		try {
			Thread.sleep(150);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		DynamicDataSource.setDataSource("dataSource1");
		System.out.println("selectBySelectedFromOther:结束");
		System.out.println("selectBySelectedFromOther:结束时间"+sdf.format(new Date()));
		return list;
	}
}

  本DB测试类(为了方便就直接在页面上用js定时器访问了)

  js文件

function checkWaring()
{
	var basePath = document.getElementById('basePath').value;
	 $.ajax({
			type : "POST",
			url : basePath + "/visitor/initVisitorReg",
			data : {
				"phone" : 151,
				"imsi" : 121
			},
			dataType : "json",
			success : function(data) {},
		error : function(data){
			console.log(data);
		}
	});
}

$(document).ready(function(){
	
	$(document).ready(function(){
		setInterval ("checkWaring()", 1000);
	});
});

  后台代码

@RequestMapping(path = "/initVisitorReg", method = RequestMethod.POST)
	@ResponseBody
	public Map<String,Object> initVisitorReg() {
//		logger.info("访客登记:开始--/initVisitorReg");
		Map<String, Object> map = new HashMap<String, Object>();
		for (int i = 0; i<20;i++) {
			System.out.println("initVisitorReg-开始");
			System.out.println(DynamicDataSource.getDataSource());
			System.out.println("initVisitorReg" + i);
			System.out.println("initVisitorReg-结束");
			if (i == 10) {
				try {
					Thread.sleep(250);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

3 思路:进行DB切换的类:5秒内切换20次,为了尽量的用足了5秒来模仿取数据时候的DB I/O花费的时间,切换一次用足了的话就是250毫秒,留了点BUFFER的话,就线程睡眠了150毫秒

      不进行DB切换的类:一秒内执行for循环20次,为了尽量仿真,访问到第十次的时候让他睡眠250毫秒,尽量让他们有交集

4 实验结果

initVisitorReg-结束
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:00.606
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:00.606
设置数据源:dataSource2
selectBySelectedFromOther:4
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:00.756
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:00.756
设置数据源:dataSource2
selectBySelectedFromOther:5
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:00.907
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:00.908
设置数据源:dataSource2
selectBySelectedFromOther:6
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:01.058
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:01.058
设置数据源:dataSource2
selectBySelectedFromOther:7
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:01.209
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:01.209
设置数据源:dataSource2
selectBySelectedFromOther:8
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg0
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg1
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg2
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg3
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg4
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg5
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg6
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg7
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg8
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg9
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg10
initVisitorReg-结束
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:01.359
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:01.359
设置数据源:dataSource2
selectBySelectedFromOther:9
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg11
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg12
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg13
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg14
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg15
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg16
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg17
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg18
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg19
initVisitorReg-结束
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:01.511
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:01.512
设置数据源:dataSource2
selectBySelectedFromOther:10
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:01.665
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:01.665
设置数据源:dataSource2
selectBySelectedFromOther:11
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:01.815
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:01.815
设置数据源:dataSource2
selectBySelectedFromOther:12
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:01.965
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:01.966
设置数据源:dataSource2
selectBySelectedFromOther:13
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:02.116
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:02.116
设置数据源:dataSource2
selectBySelectedFromOther:14
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg0
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg1
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg2
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg3
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg4
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg5
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg6
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg7
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg8
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg9
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg10
initVisitorReg-结束
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:02.266
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:02.266
设置数据源:dataSource2
selectBySelectedFromOther:15
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:02.416
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:02.417
设置数据源:dataSource2
selectBySelectedFromOther:16
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg11
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg12
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg13
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg14
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg15
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg16
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg17
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg18
initVisitorReg-结束
initVisitorReg-开始
获取数据源:dataSource1
dataSource1
initVisitorReg19
initVisitorReg-结束
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:02.568
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:02.568
设置数据源:dataSource2
selectBySelectedFromOther:17
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:02.718
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:02.718
设置数据源:dataSource2
selectBySelectedFromOther:18
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:02.868
selectBySelectedFromOther:开始
selectBySelectedFromOther:开始时间2018/04/27 12:16:02.868
设置数据源:dataSource2
selectBySelectedFromOther:19
设置数据源:dataSource1
selectBySelectedFromOther:结束
selectBySelectedFromOther:结束时间2018/04/27 12:16:03.018

  结论:网上代码还是比较靠谱的,基本上不会出现在定时器切换数据源的时候,造成本系统数据源紊乱的.

原文地址:https://www.cnblogs.com/xiaoyezi/p/8962080.html