1

I am using spring batch 2.1.9. Does this version support JTA transactions? I have a batch job definition which has multiple steps. Only one of these steps interacts with multiple datasources in Unit of Work.

Is it possible to apply JtaTransactionManager to just this step? I am getting following exception and it looks like this occurs when spring batch tries to update the metadata information in tables.

Caused by java.sql.SQLException Cannot call Connection.commit in distributed transaction. Transaction Manager will commit the resource manager when the distributed transaction is committed..

Is there any property I can set at Jta level/spring batch to avoid this?

If not step, would it work if I set JtaTxnMgr at job level? I would avoid this since other steps doesn't need to be XA-Aware txn.

org.springframework.batch.core.step.FatalStepExecutionException: JobRepository failure forcing exit with unknown status at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:441) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131) at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:264) 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:214) at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143) at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:250) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195) at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:120) at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:118) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) Caused by: org.springframework.transaction.TransactionSystemException: Could not commit JDBC transaction; nested exception is java.sql.SQLException: Cannot call Connection.commit in distributed transaction. Transaction Manager will commit the resource manager when the distributed transaction is committed. at org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DataSourceTransactionManager.java:271) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:755) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:724) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:387) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy52.updateExecutionContext(Unknown Source) at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:429) ... 15 more Caused by: java.sql.SQLException: Cannot call Connection.commit in distributed transaction. Transaction Manager will commit the resource manager when the distributed transaction is committed. at weblogic.jdbc.wrapper.JTSConnection.commit(JTSConnection.java:643) at org.springframework.jdbc.datasource.DataSourceTransactionManager.doCommit(DataSourceTransactionManager.java:268)

Zaki
  • 6,997
  • 6
  • 37
  • 53
tronline
  • 117
  • 1
  • 9

1 Answers1

1

You can specify the transaction manager on the tasklet element, allowing you to use one transaction manager on one step and others on another. See section 5.1.1 here: http://docs.spring.io/spring-batch/trunk/reference/html/configureStep.html

Michael Minella
  • 20,843
  • 4
  • 55
  • 67
  • I have JtaTxmManager set to this property of tasklet, but I ran in to the exception mentioned above. Is there a working test case? Does it mean insert/update to step_execution and other metadata tables takes part in jta transaction? – tronline Aug 20 '14 at 15:21
  • There is a single transaction for a step so yes, the expectation is that the metadata tables are participating in that transaction. Without that, you'd end up with inconsistent state between your business data and your repository if a failure occurred. – Michael Minella Aug 20 '14 at 16:07
  • JobRepository definition is using a DataSourceTransactionManager where as Step definition is using JtaTransactionManager. Will this be a problem? We have multiple jobs reusing JobRepository (which doesn't require JtaTxnManager). – tronline Aug 21 '14 at 09:46