Polish rollback rule support
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,13 +22,13 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Rule determining whether or not a given exception (and any subclasses)
|
||||
* should cause a rollback.
|
||||
* Rule determining whether or not a given exception should cause a rollback.
|
||||
*
|
||||
* <p>Multiple such rules can be applied to determine whether a transaction
|
||||
* should commit or rollback after an exception has been thrown.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Sam Brannen
|
||||
* @since 09.04.2003
|
||||
* @see NoRollbackRuleAttribute
|
||||
*/
|
||||
@@ -36,7 +36,7 @@ import org.springframework.util.Assert;
|
||||
public class RollbackRuleAttribute implements Serializable{
|
||||
|
||||
/**
|
||||
* The {@link RollbackRuleAttribute rollback rule} for
|
||||
* The {@linkplain RollbackRuleAttribute rollback rule} for
|
||||
* {@link RuntimeException RuntimeExceptions}.
|
||||
*/
|
||||
public static final RollbackRuleAttribute ROLLBACK_ON_RUNTIME_EXCEPTIONS =
|
||||
@@ -48,30 +48,31 @@ public class RollbackRuleAttribute implements Serializable{
|
||||
* This way does multiple string comparisons, but how often do we decide
|
||||
* whether to roll back a transaction following an exception?
|
||||
*/
|
||||
private final String exceptionName;
|
||||
private final String exceptionPattern;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code RollbackRuleAttribute} class.
|
||||
* Create a new instance of the {@code RollbackRuleAttribute} class
|
||||
* for the given {@code exceptionType}.
|
||||
* <p>This is the preferred way to construct a rollback rule that matches
|
||||
* the supplied {@link Exception} class, its subclasses, and its nested classes.
|
||||
* @param clazz throwable class; must be {@link Throwable} or a subclass
|
||||
* the supplied exception type, its subclasses, and its nested classes.
|
||||
* @param exceptionType exception type; must be {@link Throwable} or a subclass
|
||||
* of {@code Throwable}
|
||||
* @throws IllegalArgumentException if the supplied {@code clazz} is
|
||||
* @throws IllegalArgumentException if the supplied {@code exceptionType} is
|
||||
* not a {@code Throwable} type or is {@code null}
|
||||
*/
|
||||
public RollbackRuleAttribute(Class<?> clazz) {
|
||||
Assert.notNull(clazz, "'clazz' cannot be null");
|
||||
if (!Throwable.class.isAssignableFrom(clazz)) {
|
||||
public RollbackRuleAttribute(Class<?> exceptionType) {
|
||||
Assert.notNull(exceptionType, "'exceptionType' cannot be null");
|
||||
if (!Throwable.class.isAssignableFrom(exceptionType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot construct rollback rule from [" + clazz.getName() + "]: it's not a Throwable");
|
||||
"Cannot construct rollback rule from [" + exceptionType.getName() + "]: it's not a Throwable");
|
||||
}
|
||||
this.exceptionName = clazz.getName();
|
||||
this.exceptionPattern = exceptionType.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@code RollbackRuleAttribute} class
|
||||
* for the given {@code exceptionName}.
|
||||
* for the given {@code exceptionPattern}.
|
||||
* <p>This can be a substring, with no wildcard support at present. A value
|
||||
* of "ServletException" would match
|
||||
* {@code javax.servlet.ServletException} and subclasses, for example.
|
||||
@@ -79,40 +80,49 @@ public class RollbackRuleAttribute implements Serializable{
|
||||
* whether to include package information (which is not mandatory). For
|
||||
* example, "Exception" will match nearly anything, and will probably hide
|
||||
* other rules. "java.lang.Exception" would be correct if "Exception" was
|
||||
* meant to define a rule for all checked exceptions. With more unusual
|
||||
* meant to define a rule for all checked exceptions. With more unique
|
||||
* exception names such as "BaseBusinessException" there's no need to use a
|
||||
* fully package-qualified name.
|
||||
* @param exceptionName the exception name pattern; can also be a fully
|
||||
* @param exceptionPattern the exception name pattern; can also be a fully
|
||||
* package-qualified class name
|
||||
* @throws IllegalArgumentException if the supplied
|
||||
* {@code exceptionName} is {@code null} or empty
|
||||
* @throws IllegalArgumentException if the supplied {@code exceptionPattern}
|
||||
* is {@code null} or empty
|
||||
*/
|
||||
public RollbackRuleAttribute(String exceptionName) {
|
||||
Assert.hasText(exceptionName, "'exceptionName' cannot be null or empty");
|
||||
this.exceptionName = exceptionName;
|
||||
public RollbackRuleAttribute(String exceptionPattern) {
|
||||
Assert.hasText(exceptionPattern, "'exceptionPattern' cannot be null or empty");
|
||||
this.exceptionPattern = exceptionPattern;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the pattern for the exception name.
|
||||
* Get the configured exception name pattern that this rule uses for matching.
|
||||
* @see #getDepth(Throwable)
|
||||
*/
|
||||
public String getExceptionName() {
|
||||
return this.exceptionName;
|
||||
return this.exceptionPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the depth of the superclass matching.
|
||||
* <p>{@code 0} means {@code ex} matches exactly. Returns
|
||||
* {@code -1} if there is no match. Otherwise, returns depth with the
|
||||
* lowest depth winning.
|
||||
* Return the depth of the superclass matching, with the following semantics.
|
||||
* <ul>
|
||||
* <li>{@code -1} means this rule does not match the supplied {@code exception}.</li>
|
||||
* <li>{@code 0} means this rule matches the supplied {@code exception} exactly.</li>
|
||||
* <li>Any other positive value means this rule matches the supplied {@code exception}
|
||||
* within the superclass hierarchy, where the value is the number of levels in the
|
||||
* class hierarchy between the supplied {@code exception} and the exception against
|
||||
* which this rule matches directly.</li>
|
||||
* </ul>
|
||||
* <p>When comparing roll back rules that match against a given exception, a rule
|
||||
* with a lower matching depth wins. For example, a direct match ({@code depth == 0})
|
||||
* wins over a match in the superclass hierarchy ({@code depth > 0}).
|
||||
*/
|
||||
public int getDepth(Throwable ex) {
|
||||
return getDepth(ex.getClass(), 0);
|
||||
public int getDepth(Throwable exception) {
|
||||
return getDepth(exception.getClass(), 0);
|
||||
}
|
||||
|
||||
|
||||
private int getDepth(Class<?> exceptionClass, int depth) {
|
||||
if (exceptionClass.getName().contains(this.exceptionName)) {
|
||||
if (exceptionClass.getName().contains(this.exceptionPattern)) {
|
||||
// Found it!
|
||||
return depth;
|
||||
}
|
||||
@@ -133,17 +143,17 @@ public class RollbackRuleAttribute implements Serializable{
|
||||
return false;
|
||||
}
|
||||
RollbackRuleAttribute rhs = (RollbackRuleAttribute) other;
|
||||
return this.exceptionName.equals(rhs.exceptionName);
|
||||
return this.exceptionPattern.equals(rhs.exceptionPattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.exceptionName.hashCode();
|
||||
return this.exceptionPattern.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RollbackRuleAttribute with pattern [" + this.exceptionName + "]";
|
||||
return "RollbackRuleAttribute with pattern [" + this.exceptionPattern + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user