Results 1 to 4 of 4

Thread: Spring Batch Quartz and Transacions

  1. #1

    Default Spring Batch Quartz and Transacions

    I have the following configuration

    Job Definition

    Code:
    	
    
    <job id="thumbnailJob" incrementer="dateIncrementer">
    		<step id="step1ThumbnailReaderWriter">
    			<tasklet>
    				<listeners>
    					<listener ref="thumbnailBatchListener"/>
    				</listeners>
    				<chunk reader="thubmnailItemReader" writer="batchWritierProvider"
    					commit-interval="1" skip-limit="10000000">
    				<skippable-exception-classes>
    					java.lang.Exception
    				</skippable-exception-classes>
    
    				</chunk>
    			</tasklet>
    
    		</step>
    	</job>
    	<!-- Listener class which logs the progess of the ItemWriter + errors  -->
    
    
    	<beans:bean id="thumbnailBatchListener" class="com.siemens.c4bs.batch.ThumbnailBatchListener">
    		<beans:property name="batchLogDAO" ref="batchLogDAO"></beans:property>
    	</beans:bean>
    
    
    	<!-- ThumbnailItem reader reads files from a directors and passes them to the writer.  -->
    
    
    
    	<beans:bean id="thubmnailItemReader" class="com.siemens.c4bs.batch.DirectoryFileItemReader">
    		<beans:property name="directory" value="${thumbnail.incomingDir}"/>
    	</beans:bean>
    
    
    <beans:bean id="thumbnailJobDetail"
    		class="org.springframework.scheduling.quartz.JobDetailBean">
    		<beans:property name="jobClass"
    			value="com.siemens.c4bs.batch.RetryJobLauncherDetails" />
    		<beans:property name="group" value="quartz-batch" />
    		<beans:property name="jobDataAsMap">
    			<beans:map>
    				<beans:entry key="jobName" value="thumbnailJob" />
    				<beans:entry key="jobLocator" value-ref="jobRegistry" />
    				<beans:entry key="jobLauncher" value-ref="jobLauncher" />
    				<beans:entry key="jobOperator" value-ref="jobOperator" />
    			</beans:map>
    		</beans:property>
    	</beans:bean>

    My writer calls a service which is also used generally by the application which is transactional and I get the following exception.

    Code:
    org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@21470daa] for key [org.apache.commons.dbcp.BasicDataSource@33bdfcdb] bound to thread [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1]
    	at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:599)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:374)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:263)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
    	at com.siemens.c4bs.service.ThumbnailServiceImpl$$EnhancerByCGLIB$$1ae324ae.createThumbnail(<generated>)
    	at com.siemens.c4bs.batch.ThumbnailItemWriter.write(ThumbnailItemWriter.java:27)
    	at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:156)
    	at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:137)
    	at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$3.doWithRetry(FaultTolerantChunkProcessor.java:284)
    	at org.springframework.batch.retry.support.RetryTemplate.doExecute(RetryTemplate.java:231)
    	at org.springframework.batch.retry.support.RetryTemplate.execute(RetryTemplate.java:180)
    	at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:213)
    	at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.write(FaultTolerantChunkProcessor.java:371)
    	at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:178)
    	at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:74)
    	at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:268)
    	at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76)
    	at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
    	at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
    	at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
    	at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:242)
    	at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
    	at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:348)
    	at org.springframework.batch.core.job.flow.FlowJob.access$0(FlowJob.java:1)
    	at org.springframework.batch.core.job.flow.FlowJob$JobFlowExecutor.executeStep(FlowJob.java:135)
    	at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
    	at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
    	at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
    	at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:103)
    	at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:250)
    	at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:110)
    	at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
    	at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:105)
    	at com.siemens.c4bs.batch.RetryJobLauncherDetails.executeInternal(RetryJobLauncherDetails.java:74)
    	at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86)
    	at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:525)
    Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@21470daa] for key [org.apache.commons.dbcp.BasicDataSource@33bdfcdb] bound to thread [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1]
    	at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:182)
    	at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:574)
    	... 40 more

    My writer code

    Code:
    public class ThumbnailItemWriter<T> implements ItemWriter<T> {
    
    	private IThumbnailService thumbnailService;
    
    	@Override
    	public void write(List<? extends T> fileList) throws Exception {
    		for (Object file : fileList) {
    			thumbnailService.createThumbnail((File) file);
    		}
    	}
    
    	public IThumbnailService getThumbnailService() {
    		return thumbnailService;
    	}
    
    	public void setThumbnailService(IThumbnailService thumbnailService) {
    		this.thumbnailService = thumbnailService;
    	}
    
    }
    On removing the transactional attribute. Everything works fine. But I would prefer not to do this as this method is also used generally used in the application

  2. #2
    Join Date
    Jun 2005
    Posts
    4,241

    Default

    Just make sure you are using the same transaction manager in your service and in the Batch job repository. Easiest is to only have one, and then there can be no mistake.

  3. #3

    Default

    I added my hibernateTransactionManager to the tasklet.
    and left the other transactionManager as this needs to deal with the
    batch tables.

    Code:
    
    			<tasklet transaction-manager="hibernateTransactionManager">

  4. #4

    Default

    I also think that the transactionManager should not be autowired and the user should be forced to specify it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •