在Spring的项目中独立使用quartz, 解决 job获得service,以及事务问题 (spring不管理quartz)...

在Spring管理的项目中,使用Quartz执行CSV解析、数据库保存和地理编码等任务。为了解决job获取service和事务问题,通过自定义监听器实现QuartzInitializerListener,将ServletContext放入SchedulerContext,然后在job类中获取webApplicationContext,使用transactionManager进行事务管理。
摘要由CSDN通过智能技术生成
[b]问题背景:[/b]
项目中使用到了spring来管理bean,事务,以及hibernate的session。同时又用到quartz,执行几个任务如:csv文件解析,将文件数据保存到数据库以及调用ptv服务的geocoding等。在没有使用spring的时候,quartz中job用到的service都是手动new出来的,所以不会有问题,因为加了spring,所以需要spring来生成bean,同时保证事务正常工作。因为hibernate底层调用的是facotry.getCurrentSession()方法获得session,所以如果不加事务,那么就会报错。
[b]问题描述:[/b]
如何在生成的job中通过spring获得service,并添加事务管理?
[b]解决方法:[/b]
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.
[b]代码[/b]


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解决这个问题的方法是一样的。 :D
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值