RESOLVED - issue BATCH-572: Retryable exceptions cannot be skippable

* Deprecated StatefulRetryStepFactoryBean
* Added generic cache limit property to SkipLimitStepFactoryBean (replacing skipCacheLimit)
* Testing
This commit is contained in:
dsyer
2008-06-05 11:53:36 +00:00
parent 05b3e0ad36
commit a55e488c14
6 changed files with 110 additions and 26 deletions

View File

@@ -180,7 +180,7 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw
}
catch (Throwable e) {
logger.error("Encountered an error executing the step");
logger.error("Encountered an error executing the step: "+e.getClass()+": "+e.getMessage());
stepExecution.setStatus(determineBatchStatus(e));
exitStatus = getDefaultExitStatusForFailure(e);

View File

@@ -40,7 +40,6 @@ import org.springframework.util.Assert;
* appropriate subclass of this factory bean to configure skip or retry.
*
* @see SkipLimitStepFactoryBean
* @see StatefulRetryStepFactoryBean
*
* @author Dave Syer
*

View File

@@ -23,6 +23,7 @@ import org.springframework.batch.retry.RetryOperations;
import org.springframework.batch.retry.backoff.BackOffPolicy;
import org.springframework.batch.retry.callback.RecoveryRetryCallback;
import org.springframework.batch.retry.policy.ExceptionClassifierRetryPolicy;
import org.springframework.batch.retry.policy.MapRetryContextCache;
import org.springframework.batch.retry.policy.NeverRetryPolicy;
import org.springframework.batch.retry.policy.RecoveryCallbackRetryPolicy;
import org.springframework.batch.retry.policy.SimpleRetryPolicy;
@@ -43,7 +44,6 @@ import org.springframework.batch.support.SubclassExceptionClassifier;
* {@link #setNoRollbackForExceptionClasses(Class[])} list.
*
* @see SimpleStepFactoryBean
* @see StatefulRetryStepFactoryBean
*
* @author Dave Syer
* @author Robert Kasanicky
@@ -61,8 +61,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean {
private ItemKeyGenerator itemKeyGenerator;
// TODO: build this into the retry policy
private int skipCacheCapacity = 1024;
private int cacheCapacity = 0;
private int retryLimit;
@@ -81,6 +80,27 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean {
this.retryLimit = retryLimit;
}
/**
* Public setter for the capacity of the cache in the retry policy. If more
* items than this fail without being skipped or recovered an exception will
* be thrown. This is to guard against inadvertent infinite loops generated
* by item identity problems. If a large number of items are failing and not
* being recognized as skipped, it usually signals a problem with the key
* generation (often equals and hashCode in the item itself). So it is
* better to enforce a strict limit than have weird looking errors, where a
* skip limit is reached without anything being skipped.<br/>
*
* The default value should be high enough and more for most purposes. To
* breach the limit in a single-threaded step typically you have to have
* this many failures in a single transaction. Defaults to the value in the
* {@link MapRetryContextCache}.
*
* @param cacheCapacity the cacheCapacity to set
*/
public void setCacheCapacity(int cacheCapacity) {
this.cacheCapacity = cacheCapacity;
}
/**
* Public setter for the Class[].
* @param retryableExceptionClasses the retryableExceptionClasses to set
@@ -149,24 +169,6 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean {
this.itemKeyGenerator = itemKeyGenerator;
}
/**
* Public setter for the capacity of the skipped item cache. If a large
* number of items are failing and not being recognized as skipped, it
* usually signals a problem with the key generation (often equals and
* hashCode in the item itself). So it is better to enforce a strict limit
* than have weird looking errors, where a skip limit is reached without
* anything being skipped.<br/>
*
* The default value is 1024 which should be high enough and more for most
* purposes. To breach the limit in a single-threaded step typically you
* have to have this many failures in a single transaction.
*
* @param skipCacheCapacity the capacity to set
*/
public void setSkipCacheCapacity(int skipCacheCapacity) {
this.skipCacheCapacity = skipCacheCapacity;
}
/**
* Skippable noRollbackForExceptionClasses will *not* cause transaction
* rollback.
@@ -192,7 +194,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean {
addFatalExceptionIfMissing(RetryException.class);
SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy(retryLimit);
if (retryableExceptionClasses.length>0) { // otherwise we retry
if (retryableExceptionClasses.length > 0) { // otherwise we retry
// all exceptions
simpleRetryPolicy.setRetryableExceptionClasses(retryableExceptionClasses);
}
@@ -218,6 +220,9 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean {
RecoveryCallbackRetryPolicy recoveryCallbackRetryPolicy = new RecoveryCallbackRetryPolicy(retryPolicy);
recoveryCallbackRetryPolicy.setRecoverableExceptionClasses(noRollbackForExceptionClasses);
if (cacheCapacity > 0) {
recoveryCallbackRetryPolicy.setRetryContextCache(new MapRetryContextCache(cacheCapacity));
}
RetryTemplate retryTemplate = new RetryTemplate();
if (retryListeners != null) {

View File

@@ -39,6 +39,9 @@ import org.springframework.batch.retry.RetryPolicy;
*
* @author Dave Syer
*
* @deprecated All the features of this factory bean were moved to
* {@link SkipLimitStepFactoryBean} in version 1.1.0.
*
*/
public class StatefulRetryStepFactoryBean extends SkipLimitStepFactoryBean {