问题描述
- 在java timer定时器中调用dao层会报错
-
现在在做一个web项目,使用spring+springMVC+hibernate框架,问题描述:
项目中有一个扫描的功能,分即时任务、定时任务、周期任务三种,即时任务已经实现了,现在使用java.util.Timer、java.util.TimerTask类做定时任务,重写TimerTask的run方法,在run方法中调用之前已经没有问题的即时任务扫描方法。每次运行定时任务时,会卡在dao层方法的调用上,因为在即时任务的扫描方法中调用了dao层的数据操作方法,报错“No Session found for current thread”。即时任务的执行流程:前台提交即时任务扫描请求->控制器调用service层的立即扫描方法startImmediateTask();
定时任务的执行流程:前台提交定时任务扫描请求->控制器调用service层的定时扫描方法startTimerTask()->调用立即扫描方法startImmediateTask()。下面附上代码和配置文件,请各位大牛帮忙解决啊!
service层代码
/** * 开始定时扫描任务 * @param blTask */ public void startTimerTask(final BLTask blTask) { Date startDate = blTask.getStartTime(); TimerTask task = new TimerTask() { @Override public void run() { // 调用扫描方法 startImmediateTask(blTask); } }; Timer timer = new Timer(); timer.schedule(task, startDate); } /** * 开始即时扫描任务 * @param blTask */ public void startImmediateTask(BLTask blTask) { BLScanParam blScanParam = new BLScanParam(); BLPolicyGroup blPolicyGroup = null; // 策略组 List<BLCheckItem> blCheckItems = null; // 检查项 Map<Long, BLCheckScript> blCheckScriptMap = new HashMap<Long, BLCheckScript>(); // 检查脚本 Long pgId = null; // 策略组ID String alias = null; // 策略别名、检查项别名 Long osType = blTask.getOsType(); // 操作系统类型 List<Long> csIds = new ArrayList<Long>(); // 检查脚本ID数组 blScanParam.setBlTask(blTask); pgId = blTask.getPgId(); // 通过策略组ID查找策略组 blPolicyGroup = blPolicyGroupDao.get(pgId); if (blPolicyGroup == null) { return; } blScanParam.setBlPolicyGroup(blPolicyGroup); alias = blPolicyGroup.getAlias(); // 通过别名、操作系统类别查找所有匹配的检查项 blCheckItems = blCheckItemDao.queryByProerties(new String[]{"alias", "osType"}, new Object[]{alias, osType}); if (blCheckItems == null || blCheckItems.size() <= 0) { return; } blScanParam.setBlCheckItems(blCheckItems); for (BLCheckItem blCheckItem : blCheckItems) { csIds.add(blCheckItem.getCsId()); } int size = csIds.size(); // 获取当前策略组下的所有检查项的检测脚本 List<BLCheckScript> blCheckScripts = blCheckScriptDao.queryByProerties("csId", (Long[])csIds.toArray(new Long[size])); for (BLCheckScript blCheckScript : blCheckScripts) { // 获取当前策略组下的所有检测脚本,并放入map中 blCheckScriptMap.put(blCheckScript.getCsId(), blCheckScript); } blScanParam.setBlCheckScriptMap(blCheckScriptMap); // 分割ip为数组,传入TaskDispatch String[] ips = getIps(blTask.getIpArea()); TaskDispatch taskDispatch = new TaskDispatch(ips, blScanParam); taskDispatch.StartTask(); // 将当前TaskDispatch对象的引用放入taskDispatchMap中,供停止任务时使用 taskDispatchMap.put(blTask.getTkId(), taskDispatch); }
BaseDao的部分代码
public class BaseDao<E> implements Dao<E> { public SessionFactory getSessionFactory() { return this.sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Session getSession() { return this.sessionFactory.getCurrentSession(); } @Resource(name = "sessionFactory") public void setSF(SessionFactory sessionFactory) { setSessionFactory(sessionFactory); } }
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <context:annotation-config /> <context:component-scan base-package="com.djbh" /> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://192.168.1.247:3306/djbh_db?useUnicode=true&characterEncoding=utf-8" /> <property name="user" value="root" /> <property name="password" value="mysql" /> <!-- <property name="driverClass" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> <property name="jdbcUrl" value="jdbc:sqlserver://localhost:1433;DatabaseName=DJBH_DB" /> <property name="user" value="sa" /> <property name="password" value="123456" /> --> <property name="acquireIncrement" value="3" /> <property name="idleConnectionTestPeriod" value="120" /> <property name="initialPoolSize" value="3" /> <property name="minPoolSize" value="3" /> <property name="maxPoolSize" value="15" /> <property name="numHelperThreads" value="3" /> <property name="preferredTestQuery" value="select 1" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <!-- <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop> --> <!-- <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop> --> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.use_outer_join">true</prop> <prop key="hibernate.jdbc.fetch_size">30</prop> <prop key="hibernate.jdbc.batch_size">30</prop> <prop key="hibernate.jdbc.batch_versioned_data">true</prop> <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop> <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="javax.persistence.validation.mode">none</prop> </props> </property> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan"> <list> <value>com.djbh.model</value> </list> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 启动对@AspectJ注解的支持 --> <aop:aspectj-autoproxy/> </beans>
springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <mvc:annotation-driven/> <mvc:resources location="/static/" mapping="/static/**"/> <mvc:resources location="/attachment/report_html/" mapping="/attachment/report_html/**"/> <context:component-scan base-package="com.djbh.controller" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property> <property name="prefix"><value>/WEB-INF/page/</value></property> <property name="suffix"><value>.jsp</value></property> </bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="messages" /> <property name="useCodeAsDefaultMessage" value="true" /> </bean> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--<property name="maxUploadSize" value="10485760"></property> --> </bean> <aop:aspectj-autoproxy proxy-target-class="true" /> </beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <display-name>djbh</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:applicationContext*.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>core.web.SystemInitListener</listener-class> </listener> <filter> <filter-name>loginFilter</filter-name> <filter-class>core.web.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>characterEncoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>
解决方案
startTimerTask是什么时候调用的,贴出来的信息太少了
时间: 2024-10-24 19:43:02