事情的起因是因为我要在一个定时任务的某处将数据入库,一个是批量入库,之后再是非批量的普通方式入库,伪代码如下:
for(int i=0; i<n; i++) { //批量入库 pools.execute(new BatchSaveThread(list));//list为map集合 //普通入库 pools.execute(new SaveThread(map)); }
这个定时任务是每隔1min就触发的,频率还蛮高。而且n大约是10,pools为线程池,BatchSaveThread和SaveThread分别为批量入库的线程和普通入库的线程。
问题现象:这个定时任务放到环境上跑,发现过个5-7min就会“卡死”,即:批量入库或普通入库都不能持续,普通入库在持续最多7分钟左右就不再进行了。debug发现普通入库的线程会进入,但是就是没法往下执行。
解决:其实可以从线程的角度考虑,之前想在定时任务当中,用线程池调配线程的方式异步地入库,但由于批量入库的步骤可能需要的时间较长,所以线程在此处耗费时间较多,以至于在本分钟内没能完成,卡在这导致普通入库那一步也没有完成。
把普通入库和批量入库分为2个定时任务,一前一后的执行。普通入库先执行,在那里for循环中负责生成每次跟循环有关的list,并把他们放到内存中,之后,在晚些时候执行批量入库,再在批量入库的定时任务中for循环,取出每次的list,再针对该List入库。为进一步避免线程问题,可以摈弃异步入库,直接取代原来的入库线程而调用dao的相关入库方法,,后来发现其实也并没有消耗太多时间。
注:
1)内存存取list可以使用ServletContext的setAttribute(String key, Object obj)和getAttribute(key);取完可以removeAttribute(String key)减少内存占用~~;key的设计可以带上for循环里的元素以及时间。
2)mysql中想要真正的executeBatch()起作用,要记得在jdbc的url上加上rewriteBatchedStatements=true才行,否则批量执行是不会起作用的。
改进之后,经过长时间测试发现,无论是数据量较大的批量入库,还是普通入库,都能平稳地运行下去了。
顺便补充些小问题:
1.循环一个集合的前提是这个集合不为null,虽然默认情况下是根本不用考虑的,但如果你是通过本例中ServletContext的getAttribute(String key)这种方式,或其他方式得到List——即不是通过常见的定义方式得到的List,在循环它之前,需要做容错处理:if(list != null)再循环哦!
2.在一个定时任务类的属性定义上不要直接带上需要通过bean得到的其他bean类,否则会报空指针异常。比如我在一个定时任务类的的属性上(方法外)这样:
WebApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext();
或这样:
Dao dao = bean.get(xxxx)
都会报NullPointerException。之所以不能在方法体外的类属性上直接定义这些,是因为:定时任务类也是被配置成bean的,在Spring容器启动成功之前,整个Spring容器的环境是还未完全搭建成功的,而bean的这些属性会在把它管理之前就扫描到,所以你不能在还未完全搭建Spring环境成功就使用Spring的上下文。——这点需注意,可以延伸到任何一个需要被管理的bean,不能在方法体外部直接使用Spring上下文。
相关推荐
基于SpringBoot+layui秒级定时任务管理,crontab替代品
不错的c语言课程设计项目--产品入库管理操作系统 不错的c语言课程设计项目--产品入库管理操作系统 不错的c语言课程设计项目--产品入库管理操作系统 不错的c语言课程设计项目--产品入库管理操作系统 不错的c语言课程...
因数据库同步太耗网络资源,同步数据不多可采取产生SQL同步的方式,这个小程序,可以定时读取指定SQL文件连接数据库并执行的功能,配合ftp下载或推送就可实现同步。 采用ADO方式连接,config.ini文件可设置连接字符...
NULL 博文链接:https://yuhuiblog695685688425687986842568269.iteye.com/blog/2431363
综合技能训练二:入库任务单分析
任务入库单的制作PPT学习教案.pptx
spring定时ftp取文件入库以及报表查询.7z
编制一个用PLC控制的车辆出入库管理梯形图控制程序,控制要求如下: 1.入库车辆前进时,经过1# → 2#传感器后计数器加1,后退时经过2# → 1#传感器后计数器减1,单经过一个传感器则计数器不动作。 2.出库车辆前进...
Oracle 数据库多语言入库问题的解决方案 本文通过研究Oracle 数据库如何成功实现多语言入库,给出了一种实现多国语言信 息存储的基本方法,该方法解决了非中文语言入库时出现的乱码问题。随着企业在发展过程 中业务...
基于WEB的仓库管理系统主要用于实现仓库的出入库管理,基本功能包括:入库模块、出库模块、商品查看模块、用户注册模块、个人信息管理模块等。本系统结构如下: 入库模块:入库新商品,或者是入库已有商品。 出库...
成品仓储出入库RFID项目解决方案.doc
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业...基于MATLAB的汽车出入库计时计费系统源码+项目说明(有GUI界面,分汽车入库和汽车出库2个模块).zip
场景:页面上传excle表,表中数据约10万,关键是后台逻辑输出数据的处理,避免出现空指针(空值) 目的:excle上传成功,数据入库成功。
贫困地区儿童营养改善项目营养包发放出入库登记表.pdf
固定资产投资项目入库纳统工作流程及具体要求.doc
Java实现商品的查找、添加、出库、入库等操作,步骤非常详细,适合小白。
基于C和C++的二维码扫码出入库管理系统+sln解决方案.zip基于C和C++的二维码扫码出入库管理系统+sln解决方案.zip基于C和C++的二维码扫码出入库管理系统+sln解决方案.zip基于C和C++的二维码扫码出入库管理系统+sln解决...
页面excle表导入大批量数据批量入库的边界值判断,假设excle表10万数据,5000为一批,10万是可以被5000整除的,那么此时整除的边界要进行处理(具体参见代码,以代码为列子阐述),否则会可能将会在最后一次出现null...
Steam一键入库工具,助力Steam游戏开发者。