|
|
Hi All,
We have the following scenario:
We have a job with ItemReader, Processor and Writer.
ItemReader - read the data from database.
The ItemProcessor processes the records(record multiple tables). During this processing if any business exception is thrown, currently processed records need to rollback. After the rollback of the chunk the batch job should continue with the next item.
I am using org..orm.hibernate3.HibernateTransa ctionManager,
Spring batch 2.1
lt;codegt;
lt;job id=quot;Load_ReturnedJobquot; restartable=quot;truequot;
xmlns=quot;schema/batchquot;gt;
lt;step id=quot;Load_ReturnedStepquot;gt;
lt;taskletgt;
lt;chunk reader=quot;commonListItemReaderquot;
processor=quot;StopOrderProcessorquot;
writer=quot;commonListWriterquot; commit-interval=quot;1quot;gt;
lt;/chunkgt;
lt;listenersgt;
lt;listener ref=quot;loadReturnedListenerquot; /gt;
lt;/listenersgt;
lt;/taskletgt;
lt;/stepgt;
lt;/jobgt;
lt;/codegt;
How to rollback the transaction?
I tried to use Programmatic transaction management still the transaction is committed.
lt;codegt;
lt;job id=quot;Load_ReturnedJobquot; restartable=quot;truequot;
xmlns=quot;schema/batchquot;gt;
lt;step id=quot;Load_ReturnedStepquot;gt;
lt;taskletgt;
lt;chunk reader=quot;commonListItemReaderquot;
processor=quot;StopOrderProcessorquot;
writer=quot;commonListWriterquot; commit-interval=quot;1quot;gt;
lt;/chunkgt;
lt;listenersgt;
lt;listener ref=quot;loadReturnedListenerquot; /gt;
lt;/listenersgt;
lt;/taskletgt;
lt;/stepgt;
lt;/jobgt;
lt;bean id=quot;StopOrderProcessorquot;
class=quot;batch.processreturneddds.processor.LoadRetu rnedDDsSosProcessorquot;gt;
lt;property name=quot;transactionTemplatequot;gt;
lt;ref bean=quot;sharedTransactionTemplatequot; /gt;
lt;/propertygt;
lt;/beangt;
lt;bean id=quot;sharedTransactionTemplatequot;
class=quot;org..transaction.support.Tra nsactionTemplatequot;gt;
lt;property name=quot;isolationLevelNamequot; value=quot;ISOLATION_READ_UNCOMMITTEDquot; /gt;
lt;property name=quot;transactionManagerquot;gt;
lt;ref bean=quot;transactionManagerquot; /gt;
lt;/propertygt;
lt;/beangt;
lt;bean id=quot;loadReturnedDDsSosListenerquot;
class=quot;batch.processreturneddds.listener.LoadRetur nedDDsSosListenerquot;gt;
lt;/beangt;lt;bean id=quot;transactionManagerquot;
class=quot;org..orm.hibernate3.Hibernat eTransactionManagerquot;
lazy-init=quot;truequot;gt;
lt;property name=quot;sessionFactoryquot;gt;
lt;ref bean=quot;batchSessionFactoryquot; /gt;
lt;/propertygt;
lt;property name=quot;nestedTransactionAllowedquot; value=quot;truequot;gt;
lt;/propertygt;
lt;/beangt;
lt;/codegt;lt;codegt;
public class LoadReturnedDDsSosProcessor implements ItemProcessorlt;RunTaskListItemDo, RunTaskListItemDogt; {
/** The Constant LOGGER. */ private static final Logger LOGGER = Logger.getLogger(LoadReturnedDDsSosProcessor.class );
/** The transaction template. */ private TransactionTemplate transactionTemplate;
/** * @param transactionTemplate the transactionTemplate to set */ public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; }
/** * Process Returned Direct Debit and Stop orders. * * @param runTaskListItemDo * the run task list item do * @return ReturnedDirectDebitRequestDo, the ReturnedDirectDebitRequestDo. * @throws Exception * the Exception. */ public RunTaskListItemDo process(final RunTaskListItemDo runTaskListItemDo) throws Exception {
LOGGER.debug(quot;Entered LoadReturnedDDsSosProcessor.quot;); transactionTemplate.setPropagationBehavior(Transac tionDefinition.PROPAGATION_NESTED); transactionTemplate.execute(new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(TransactionStatus status) { try { // call business functionality } catch (DirectDebitException directDebitException) { LOGGER.error(directDebitException.getExceptionNoti ficationList().getExceptionNotification().get(0) .getMessage()); status.setRollbackOnly(); } } }); return runTaskListItemDo; }
}
lt;/codegt;
How to rollback the chunk?
Thanks for ur reply in advance.
You simply need to define a transaction manager for your tasklet in the step.
lt;tasklet transaction-manager=quot;transactionManagerquot;gt;
...
lt;/taskletgt;
lt;bean id=quot;transactionManagerquot; class=quot;org..jdbc.datasource.DataSou rceTransactionManagerquot;gt; lt;property name=quot;dataSourcequot; ref=quot;...quot; /gt;
lt;/beangt;
With the Spring transaction manager defined, execute() of the tasklet runs as a Spring transactional method. By default, an exception thrown in execute() will roll back all the SQL statements executed in the transactional execute().
Thanks for your reply.
We have the following scenario:
We have a job with ItemReader, Processor and Writer.
ItemReader - read the data from database.
The ItemProcessor processes the records(record multiple tables). During this processing if any business exception is thrown, currently processed records need to rollback. After the rollback of the chunk the batch job should continue with the next item.
If business Exception occurs how can we rollback the transcation?
an exception from the item processor triggers a rollback for the chunk. But by default, it's going to fail the step execution. If you don't want this, configure the business exception as a skippable exception.
Thanks for your reply.
My Batch Runs every day.
On Month ends i will get even one billion records. All the one billion records can satisfy the business flow and throws the business exception.
If I am using Skippable Exception then i need to set the skip limit. Upfront i cann't determine the skip limit.
you can specify your own skip policy if you don't want to deal with a skip limit. But if you face a lot of incorrect records, you should perhaps implement an item processor to filter them. This would lead to fewer rollbacks and make the job faster. |
|