Spring Batch偶尔获取java.lang.IllegalStateException:在JobRepository中检测到现有事务

时间:2014-08-17 13:34:52

标签: transactions quartz-scheduler spring-batch

我的项目从Quartz调度程序(版本2,2,0)执行基于Spring批处理(版本2.1.9)的任务 我们正在一个多租户环境中工作,每个租户都在托管专用架构上维护自己的工作存储库。 数据源植入是租户敏感的,每个租户的池连接。 使用的事务管理器是org.springframework.jdbc.datasource.DataSourceTransactionManager

当我们执行调度程序时,任务成功执行。 有一段时间我从春季批次中得到以下异常。 请注意,其他任务也共享此调度程序。他们中的一些人有 分配给他们的其他PlatformTransactionManagers。

2014-08-14 17:10:00,082 INFO [tenant_id] [org.quartz.core.JobRunShell] - <Job ROOT_GROUP. dataGenerator threw a JobExecutionException: >
org.quartz.JobExecutionException: java.lang.IllegalStateException: Existing transaction detected in JobRepository.
Please fix this and try again (e.g. remove @Transactional annotations from client).
[See nested exception: java.lang.IllegalStateException: Existing transaction detected in JobRepository.
Please fix this and try again (e.g. remove @Transactional annotations from client).] 

使用@Transactional时我熟悉此异常(请参阅我的帖子here)。
但是,由于我的Job实际上是从调度程序运行的,并且作为一个独立的应用程序,这不是配置问题,因为偶尔会发生这种情况。 我想在某个阶段,交易会以Spring Batch认为共享交易的方式延迟。 或者在将线程返回到Quartz线程池之前,其他任务可能无法正确清除TransactionSynchronizationManager

<bean id="jobTransactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="jobDataSource" />
</bean> 
<bean
    class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
    <property name="jobRegistry" ref="jobRegistry" />
</bean>

<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="dataSource" ref="jobDataSource"/>
    <property name="databaseType" value="SQLSERVER"/>
    <property name="transactionManager" ref="jobTransactionManager"/>
</bean>

知道如何追查这个问题吗? 请在下面找到完整的堆栈跟踪:

2014-08-14 11:50:00,157 INFO [tenant_id] [org.quartz.core.JobRunShell] - <Job ROOT_GROUP.dataGenerator threw a JobExecutionException: >
org.quartz.JobExecutionException: java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove @Transactional annotations from client). [See nested exception: java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove @Transactional annotations from client).]
    at com.my.csd.scheduler.BatchJobWrapper.executeInternal(BatchJobWrapper.java:53)
    at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:111)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:207)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:560)
Caused by: java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove @Transactional annotations from client).
    at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:164)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy256.createJobExecution(Unknown Source)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:111)
    at org.springframework.batch.core.launch.support.SimpleJobOperator.startNextInstance(SimpleJobOperator.java:345)
    at org.springframework.batch.core.launch.support.SimpleJobOperator$$FastClassBySpringCGLIB$$44ee6049.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:640)
    at org.springframework.batch.core.launch.support.SimpleJobOperator$$EnhancerBySpringCGLIB$$540a28da.startNextInstance(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:201)
    at com.sun.proxy.$Proxy257.startNextInstance(Unknown Source)
    at com.my.csd.schedule.tasks.SpringBatchTask.process(SpringBatchTask.java:32)
    at com.my.csd.schedule.tasks.AbstractScheduledTask.process(AbstractScheduledTask.java:64)
    at com.my.csd.scheduler.BatchJobWrapper.process(BatchJobWrapper.java:60)
    at com.my.csd.scheduler.BatchJobWrapper.executeInternal(BatchJobWrapper.java:49)
    ... 3 more

0 个答案:

没有答案