Skip to content

Commit

Permalink
fix: Catch retryable exceptions thrown by SDN itself. (#2945)
Browse files Browse the repository at this point in the history
This fix #2944 by making the retryable exception messages consistent by introducing constants for prematurely closed transactions and sessions omitting the trailing dot as agreed within the bigger Spring Data team.
  • Loading branch information
GregDThomas authored and michael-simons committed Aug 27, 2024
1 parent 8e3152f commit baa7fbb
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.neo4j.driver.exceptions.TransientException;
import org.springframework.dao.TransientDataAccessResourceException;


/**
* A predicate indicating {@literal true} for {@link Throwable throwables} that can be safely retried and {@literal false}
* in any other case. This predicate can be used for example with Resilience4j.
Expand All @@ -37,9 +38,12 @@
@API(status = API.Status.STABLE, since = "6.0")
public final class RetryExceptionPredicate implements Predicate<Throwable> {

public static final String TRANSACTION_MUST_BE_OPEN_BUT_HAS_ALREADY_BEEN_CLOSED = "Transaction must be open, but has already been closed";
public static final String SESSION_MUST_BE_OPEN_BUT_HAS_ALREADY_BEEN_CLOSED = "Session must be open, but has already been closed";
private static final Set<String> RETRYABLE_ILLEGAL_STATE_MESSAGES = Set.of(
"Transaction must be open, but has already been closed.",
"Session must be open, but has already been closed.");
TRANSACTION_MUST_BE_OPEN_BUT_HAS_ALREADY_BEEN_CLOSED,
SESSION_MUST_BE_OPEN_BUT_HAS_ALREADY_BEEN_CLOSED
);

@Override
public boolean test(Throwable throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.neo4j.driver.Transaction;
import org.springframework.data.neo4j.core.DatabaseSelection;
import org.springframework.data.neo4j.core.UserSelection;
import org.springframework.data.neo4j.core.support.RetryExceptionPredicate;
import org.springframework.lang.Nullable;
import org.springframework.transaction.support.ResourceHolderSupport;
import org.springframework.util.Assert;
Expand Down Expand Up @@ -68,7 +69,7 @@ Transaction getTransaction(DatabaseSelection inDatabase, UserSelection asUser) {

Collection<Bookmark> commit() {

Assert.state(hasActiveTransaction(), "Transaction must be open, but has already been closed");
Assert.state(hasActiveTransaction(), RetryExceptionPredicate.TRANSACTION_MUST_BE_OPEN_BUT_HAS_ALREADY_BEEN_CLOSED);
Assert.state(!isRollbackOnly(), "Resource must not be marked as rollback only");

transaction.commit();
Expand All @@ -79,15 +80,15 @@ Collection<Bookmark> commit() {

void rollback() {

Assert.state(hasActiveTransaction(), "Transaction must be open, but has already been closed");
Assert.state(hasActiveTransaction(), RetryExceptionPredicate.TRANSACTION_MUST_BE_OPEN_BUT_HAS_ALREADY_BEEN_CLOSED);

transaction.rollback();
transaction.close();
}

void close() {

Assert.state(hasActiveSession(), "Session must be open, but has already been closed");
Assert.state(hasActiveSession(), RetryExceptionPredicate.SESSION_MUST_BE_OPEN_BUT_HAS_ALREADY_BEEN_CLOSED);

if (hasActiveTransaction()) {
transaction.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
class RetryExceptionPredicateTest {

@ParameterizedTest
@ValueSource(strings = { "Transaction must be open, but has already been closed.",
"Session must be open, but has already been closed." })
@ValueSource(strings = { "Transaction must be open, but has already been closed",
"Session must be open, but has already been closed" })
void shouldRetryOnSomeIllegalStateExceptions(String msg) {

RetryExceptionPredicate predicate = new RetryExceptionPredicate();
Expand Down

0 comments on commit baa7fbb

Please sign in to comment.