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