Hi, I'm now using spring batch in a project for batch processing but encounter a complex problem about concurrent access.
We use MDB to trigger batch processing. On recieving a message, MDB triggers spring batch job based on job id in the message. To simplify the scenario, let's assume that there's only one job defined in the context. The job will enventually triggers some business services so there are a lot of business service beans loaded.
To save resource (processing power, memory, etc), MDBs (e.g pool size 10) share a same spring context which includes spring batch jobs. This means multiple threads will call up the job at the same time.
But we found exception was thrown when 2 MDB instances process the same job at the same time:
I read some recommandations that each job had better have its own spring context. But as said above, it's very expensive in my case as many many service beans need to be loaded. I've actually try this but eventually got out of memory exception.Code:org.springframework.batch.core.step.AbstractStep$FatalException: Fatal error detected during save of step execution context at org.springframework.batch.core.step.item.ItemOrientedStep$1.doInIteration(ItemOrientedStep.java:265) at org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate$ExecutingRunnable.run(TaskExecutorRepeatTemplate.java:215) at org.springframework.scheduling.commonj.DelegatingWork.run(DelegatingWork.java:61) at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1114) at com.ibm.ws.asynchbeans.WorkWithExecutionContextImpl.go(WorkWithExecutionContextImpl.java:195) at com.ibm.ws.asynchbeans.CJWorkItemImpl.run(CJWorkItemImpl.java:187) at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1469) Caused by: org.springframework.dao.OptimisticLockingFailureException: Attempt to update step execution id=1076 with wrong version (3), where current version is 2 at org.springframework.batch.core.repository.dao.JdbcStepExecutionDao.updateStepExecution(JdbcStepExecutionDao.java:334) at org.springframework.batch.core.repository.support.SimpleJobRepository.saveOrUpdate(SimpleJobRepository.java:239) at org.springframework.batch.core.repository.support.SimpleJobRepository.saveOrUpdateExecutionContext(SimpleJobRepository.java:248) at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:615) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:296) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy40.saveOrUpdateExecutionContext(Unknown Source) at org.springframework.batch.core.step.item.ItemOrientedStep$1.doInIteration(ItemOrientedStep.java:260) ... 6 more
I think SimpleStepFactoryBean/ItemOrientedStep is not thread safe. Can anyone give me some suggestions what I can do?![]()



Reply With Quote