Announcement Announcement Module
No announcement yet.
concurrent access of simple step Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • concurrent access of simple step

    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:

    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(
    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(
    	at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(
    	at java.lang.reflect.Method.invoke(
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(
    	at $Proxy40.saveOrUpdateExecutionContext(Unknown Source)
    	at org.springframework.batch.core.step.item.ItemOrientedStep$1.doInIteration(
    	... 6 more
    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.

    I think SimpleStepFactoryBean/ItemOrientedStep is not thread safe. Can anyone give me some suggestions what I can do?

  • #2
    B.1.1. Version
    Many of the database tables discussed in this appendix contain a version column. This column is important
    because Spring Batch employs an optimistic locking strategy when dealing with updates to the database. This
    means that each time a record is 'touched' (updated) the value in the version column is incremented by one.
    When the repository goes back to try and save the value, if the version number has change it will throw
    OptimisticLockingFailureException, indicating there has been an error with concurrent access. This check is
    necessary, since even though different batch jobs may be running in different machines, they are all using the
    same database tables.

    please be noted the optimistic locking strategy of spring batch, just curious why you need 2 MDBs kick off the same job?