问题背景:
项目中使用到了spring来管理bean,事务,以及hibernate的session。同时又用到quartz,执行几个任务如:csv文件解析,将文件数据保存到数据库以及调用ptv服务的geocoding等。在没有使用spring的时候,quartz中job用到的service都是手动new出来的,所以不会有问题,因为加了spring,所以需要spring来生成bean,同时保证事务正常工作。因为hibernate底层调用的是facotry.getCurrentSession()方法获得session,所以如果不加事务,那么就会报错。
问题描述:
如何在生成的job中通过spring获得service,并添加事务管理?
解决方法:
1. 自定义一个Listenner类,继承QuartzInitializerListener类,并把listener配置到web.xml中。(这个原理和spring启动的时候配置的ContextLoaderListener是一个道理,都是实现了ServletContextListener接口。所以在启动的时候可以获得servletContext).
(详细介绍可以参考:http://www.xuebuyuan.com/2041126.html)
2. 重写Listenner类的contextInitialized方法,并把ServletContext放到SchedulerContext中。(SchedulerContext可以看做类似ServletContext的类,多个sheduler共享同一个SchedulerContext)
3. 在job类中获得servletContext,再通过servletContext获得webApplicationContext.然后获得transactionmanager添加编程式事务,在业务代码中getBean获得service.
代码
public class MyQuartZInitializerListener extends QuartzInitializerListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
super.contextInitialized(sce);
ServletContext sc = sce.getServletContext();
StdSchedulerFactory fac = (StdSchedulerFactory) sc.getAttribute(QUARTZ_FACTORY_KEY);
try {
fac.getScheduler().getContext().put("sct", sc);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
de.haiberg.adman.portal.util.VmapQuartZInitializerListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/springdef/spring-datasource.xml
</param-value>
</context-param>
<!-- Hibernate Tranaction Manager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
@Service
public class MyJob implements StatefulJob {
private static Logger log = Logger.getLogger(MyJob.class);
XDaoImpl xDaoImpl;
public void execute(JobExecutionContext jobContext) throws JobExecutionException {
ServletContext sct = null;
try {
sct = (ServletContext) jobContext.getScheduler().getContext().get("sct");
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WebApplicationContext webctx = (WebApplicationContext) sct
.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
xDaoImpl = webctx.getBean("xDaoImpl", XDaoImpl.class);
// add transaction manually
HibernateTransactionManager transactionManager = (HibernateTransactionManager) webctx
.getBean("transactionManager");
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus status = transactionManager.getTransaction(def);
// business code
//xxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxx
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
log.error("Error[xxxxxx}]: " + e, e);
}
}
}
后面看到了这篇文章http://blog.csdn.net/mmm123lmj/article/details/6741994,发现spring集成quartz解决这个问题的方法是一样的。
分享到:
相关推荐
各种企业应用几乎都会碰到任务调度的需求...对于一个典型的MIS系统来说,在每月1号凌晨统计上个月各部门的业务数据生成月报表,每半个小时查询用户是否已经有快到期的待处理业 务……,这样的例子俯拾皆是,不胜枚举。
NULL 博文链接:https://dolphin-ygj.iteye.com/blog/368874
最近公司项目上线,需要把app部署在多台服务器上,但只能让其中一台服务器的job执行,一台服务器挂了,另一台还能继续执行job,通过网上查找资料,都是java工程的方式,不好部署并测试,经过二天辛苦整合,终于整理成...
也许大多数人听说 Quartz 是在学习或使用 Spring 的时 候,也就是 Spring 整合了 Quartz。而我也不例外,同样是在春天里得悉了这块石英。 当初公司一个项目中有些定时候任务,原来是用 JDK 的 TaskTimer 来实现的,...
spring和quartz的定时器的启动和停止例子
专业书 Spring Quatz 书-Quartz.Job.Scheduling.Framework.Building
这个是spring 和 quartz的集成,quartz是单独的包,java线程的方式运行,利用自定义Jobfactory来解决spring注入service空指针的问题,简单实例执行main方法即可,很实用
主要介绍了Spring quartz Job依赖注入使用详解的相关资料,Spring quartz Job不能依赖注入,Spring整合quartz Job任务不能注入Spring4整合quartz2.2.3中Job任务使用@Autowired不能注入,需要的朋友可以参考下
Spring集成quartz跑定时任务实例 自己写的例子并为实现job 有测试的主函数,请参考http://www.blogjava.net/baoyaer/articles/155645.html 博客信息 看此代码,项目里分为两大块,com文件夹下 为上面博客相关学习...
在eclipse中导出为可执行的jar,无需部署到任何web容器中。直接通过bat或shell启动即可。 系统启动时自动从数据库中读取框架配置信息,job信息,调度信息注入到框架中。 本系统内嵌了jetty作为框架的web接口为本框架...
quartz2.2/struts2/spring的整合demo,包含一个job和多个job的创建,已经测试过了,可以使用........ quartz2.2/struts2/spring的整合demo,包含一个job和多个job的创建,已经测试过了,可以使用........ quartz2.2/...
spring boot集成quartz定时器,job支持spring的依赖注入
针对Quartz与Spring做集群的Demo实例,主要解决了Quartz的JOB序列化问题。 源代码说明: support pkg:扩展Spring与Quartz集成的不足之处。 core pkg: 是自身调度业务的封装 实例运行依赖Oracle数据库,根据quartz...
大多数人听说 Quartz 是在学习或使用 Spring 的时候,也就是 Spring 整合了 Quartz。 把本人博客上零零散散,顺序错乱的各篇译章汇集成册,做成了一个 《Quartz Job Scheduling Framework 中文版.chm 》文件与各位...
Spring Job 配置详解,Spring中Quartz的Cron配置说明,一个Cron-表达式是一个由六至七个字段组成由空格分隔的字符串,其中6个字段是必须的而一个是可选的
主要解决两库的两个表数据迁移和同步问题(两个表的字段可以不一致,只要知道对应关系及转化规则即可),曾经测试过350万数据10分钟内迁移完毕 相关技术: mybatis、springBatch、mysql、quartz、spring、springMVC ...
Spring3.2.4+Quartz2.2.0 实例 <!-- 启动触发器的配置开始 --> class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- 启动触发器的配置结束 --> <!-- 调度的配置...
要解决问题 ;所以博主自己开发了一个elastic job 的spring boot starter自动装载模块;目前 该starter已经在公司多个项目生产环境运行。研发只需关注实现job和在application.yml增 加相应配置即可。 模块运行...
一个基于springboot的quartz集群dome。 向http://localhost:9090/job/addjob注入3个参数 类名:(及时定时任务的类如:com.ybjdw.site.job.NewJob) 组名:随意 定时启动方法:如“0/3 * * * * ?”(每3秒启动一次...
spring-boot集成quartz实现动态任务管理,采用数据库存储方式,建表语句已经打包在一起,支持分布式集群。 代码开箱即用,没有集成业务模块,大家可以根据自己的业务场景自己去实现Job类即可。