List of usage examples for org.springframework.batch.core.step.item Chunk setBusy
public void setBusy(boolean busy)
From source file:org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.java
@Override protected Chunk<O> getAdjustedOutputs(Chunk<I> inputs, Chunk<O> outputs) { @SuppressWarnings("unchecked") UserData<O> data = (UserData<O>) inputs.getUserData(); Chunk<O> previous = data.getOutputs(); Chunk<O> next = new Chunk<O>(outputs.getItems(), previous.getSkips()); next.setBusy(previous.isBusy()); // Remember for next time if there are skips accumulating data.setOutputs(next);//from w w w . jav a 2s .co m return next; }
From source file:org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.java
@Override protected void write(final StepContribution contribution, final Chunk<I> inputs, final Chunk<O> outputs) throws Exception { @SuppressWarnings("unchecked") final UserData<O> data = (UserData<O>) inputs.getUserData(); final AtomicReference<RetryContext> contextHolder = new AtomicReference<RetryContext>(); RetryCallback<Object, Exception> retryCallback = new RetryCallback<Object, Exception>() { @Override/* w ww . java2 s.c om*/ public Object doWithRetry(RetryContext context) throws Exception { contextHolder.set(context); if (!data.scanning()) { chunkMonitor.setChunkSize(inputs.size()); try { doWrite(outputs.getItems()); } catch (Exception e) { if (rollbackClassifier.classify(e)) { throw e; } /* * If the exception is marked as no-rollback, we need to * override that, otherwise there's no way to write the * rest of the chunk or to honour the skip listener * contract. */ throw new ForceRollbackForWriteSkipException( "Force rollback on skippable exception so that skipped item can be located.", e); } contribution.incrementWriteCount(outputs.size()); } else { scan(contribution, inputs, outputs, chunkMonitor, false); } return null; } }; if (!buffering) { RecoveryCallback<Object> batchRecoveryCallback = new RecoveryCallback<Object>() { @Override public Object recover(RetryContext context) throws Exception { Throwable e = context.getLastThrowable(); if (outputs.size() > 1 && !rollbackClassifier.classify(e)) { throw new RetryException("Invalid retry state during write caused by " + "exception that does not classify for rollback: ", e); } Chunk<I>.ChunkIterator inputIterator = inputs.iterator(); for (Chunk<O>.ChunkIterator outputIterator = outputs.iterator(); outputIterator.hasNext();) { inputIterator.next(); outputIterator.next(); checkSkipPolicy(inputIterator, outputIterator, e, contribution, true); if (!rollbackClassifier.classify(e)) { throw new RetryException( "Invalid retry state during recovery caused by exception that does not classify for rollback: ", e); } } return null; } }; batchRetryTemplate.execute(retryCallback, batchRecoveryCallback, BatchRetryTemplate.createState(getInputKeys(inputs), rollbackClassifier)); } else { RecoveryCallback<Object> recoveryCallback = new RecoveryCallback<Object>() { @Override public Object recover(RetryContext context) throws Exception { /* * If the last exception was not skippable we don't need to * do any scanning. We can just bomb out with a retry * exhausted. */ if (!shouldSkip(itemWriteSkipPolicy, context.getLastThrowable(), -1)) { throw new ExhaustedRetryException( "Retry exhausted after last attempt in recovery path, but exception is not skippable.", context.getLastThrowable()); } inputs.setBusy(true); data.scanning(true); scan(contribution, inputs, outputs, chunkMonitor, true); return null; } }; if (logger.isDebugEnabled()) { logger.debug("Attempting to write: " + inputs); } try { batchRetryTemplate.execute(retryCallback, recoveryCallback, new DefaultRetryState(inputs, rollbackClassifier)); } catch (Exception e) { RetryContext context = contextHolder.get(); if (!batchRetryTemplate.canRetry(context)) { /* * BATCH-1761: we need advance warning of the scan about to * start in the next transaction, so we can change the * processing behaviour. */ data.scanning(true); } throw e; } } callSkipListeners(inputs, outputs); }
From source file:org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.java
private void scan(final StepContribution contribution, final Chunk<I> inputs, final Chunk<O> outputs, ChunkMonitor chunkMonitor, boolean recovery) throws Exception { @SuppressWarnings("unchecked") final UserData<O> data = (UserData<O>) inputs.getUserData(); if (logger.isDebugEnabled()) { if (recovery) { logger.debug("Scanning for failed item on recovery from write: " + inputs); } else {//from w w w .j a v a 2 s. c o m logger.debug("Scanning for failed item on write: " + inputs); } } if (outputs.isEmpty() || inputs.isEmpty()) { data.scanning(false); inputs.setBusy(false); chunkMonitor.resetOffset(); return; } Chunk<I>.ChunkIterator inputIterator = inputs.iterator(); Chunk<O>.ChunkIterator outputIterator = outputs.iterator(); List<O> items = Collections.singletonList(outputIterator.next()); inputIterator.next(); try { writeItems(items); // If successful we are going to return and allow // the driver to commit... doAfterWrite(items); contribution.incrementWriteCount(1); inputIterator.remove(); outputIterator.remove(); } catch (Exception e) { try { doOnWriteError(e, items); } finally { Throwable cause = e; if (e instanceof StepListenerFailedException) { cause = e.getCause(); } if (!shouldSkip(itemWriteSkipPolicy, cause, -1) && !rollbackClassifier.classify(cause)) { inputIterator.remove(); outputIterator.remove(); } else { checkSkipPolicy(inputIterator, outputIterator, cause, contribution, recovery); } if (rollbackClassifier.classify(cause)) { throw (Exception) cause; } } } chunkMonitor.incrementOffset(); if (outputs.isEmpty()) { data.scanning(false); inputs.setBusy(false); chunkMonitor.resetOffset(); } }