应用程序服务器上的Spring Batch:在afterJob侦听器上找不到JobExecution

时间:2014-10-03 12:06:05

标签: spring-batch application-server

我是Spring批处理和Spring的新手。我正在开发一个将在WebSphere Application Server上运行的批处理作业。到目前为止,我刚刚建立了一个带有一些虚拟步骤的骨架。我还有一个监听器,用于在作业结束时更新一些Oracle DB表。这是我的appContext的一部分:

<batch:job id="spedizioneJob" restartable="true" parent="bankitJob">
        <batch:step id="verifyInputStep" next="technicalPropertiesEnforcementStep">
            <batch:tasklet ref="verifyInput" />
        </batch:step>
        <batch:step id="technicalPropertiesEnforcementStep" next="protocolAndProbatoryStep">
            <batch:tasklet ref="technicalPropertiesEnforcement" />
        </batch:step>
        <batch:step id="protocolAndProbatoryStep" next="exdiSendingStep">
            <batch:tasklet ref="protocolAndProbatory" />
        </batch:step>
        <batch:step id="exdiSendingStep">
            <batch:tasklet ref="exdiSending" />
        </batch:step>
        <batch:listeners merge="true">
            <batch:listener ref="spedizioneJobListener" />
        </batch:listeners>
    </batch:job>

这里是开始之后的片段:

public void afterJob(JobExecution jobExecution) {

    // get params
    String iref = jobExecution.getJobParameters().getString("APPL_REQ_ID");
    SpedizioneInput spInput=(SpedizioneInput)jobExecution.getExecutionContext().get("input");

奇怪的是,在我的一些测试运行中(Rational Application Developer上的本地测试环境,但同样发生在WAS的服务器上),通常不是第一个,找不到jobExecution而且我得到了这个例外:

[03/10/14 12.47.48:505 CEST] 0000003a AbstractJob   E org.springframework.batch.core.job.AbstractJob execute Encountered fatal error executing job
                                 org.springframework.batch.core.repository.dao.NoSuchObjectException: Invalid JobExecution, ID 224 not found.
    at org.springframework.batch.core.repository.dao.JdbcJobExecutionDao.updateJobExecution(JdbcJobExecutionDao.java:218)
    at org.springframework.batch.core.repository.support.SimpleJobRepository.update(SimpleJobRepository.java:160)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:600)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at $Proxy36.update(Unknown Source)
    at org.springframework.batch.core.job.AbstractJob.updateStatus(AbstractJob.java:416)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:299)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
    at java.lang.Thread.run(Thread.java:736)

我不知道这是否与我的工作方式有关......我配置了这样一种启动器:

<bean id="jobLauncher"
    class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
    <property name="taskExecutor">
        <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
    </property>
</bean>

我从一个Servlet启动invoket的Session EJB启动我的工作。这是启动时的EJB代码:

try {
            System.out.println("Before launching spedizione job");
            JobExecution jexec=jobLauncher.run(job, jpb.toJobParameters());
            System.out.println("After launching spedizione job "+jexec.getJobConfigurationName()+" status "+jexec.getStatus().toString());

我的日志确认这是按预期发出对作业的异步调用,但我怀疑在作业进入侦听器的afterJob方法之前,会话bean事务有时可能没有提交...

提前感谢您的回复

1 个答案:

答案 0 :(得分:0)

正如迈克尔所建议的那样,问题在于交易经理我是否正在使用。当我切换到WebSphereUowTransactionManager时,我解决了我的问题。 http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/jta/WebSphereUowTransactionManager.html