• 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
    

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

  • 相关阅读:
    子网划分
    数据报分片
    CRC校验
    内部网关协议RIP与OSPF的特点、区别
    简述协议与服务的区别、关系
    算法思想
    上机实验题7--求解装载问题
    上机实验题6--求最长单调递增子序列
    python进程和线程
    python序列化操作
  • 原文地址:https://www.cnblogs.com/xiaoyezi/p/8962080.html
Copyright © 2020-2023  润新知