GH-2463 - Apply default transaction timeout if possible.

This applies the default transaction timeout of the platform transaction
manager when the transaction definition is using the default.
This commit is contained in:
Michael Simons
2022-01-12 17:21:51 +01:00
parent 906c99e35a
commit b15a8cc61d
4 changed files with 42 additions and 3 deletions

View File

@@ -148,7 +148,7 @@ public class Neo4jTransactionManager extends AbstractPlatformTransactionManager
protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
Neo4jTransactionObject transactionObject = extractNeo4jTransaction(transaction);
TransactionConfig transactionConfig = Neo4jTransactionUtils.createTransactionConfigFrom(definition);
TransactionConfig transactionConfig = Neo4jTransactionUtils.createTransactionConfigFrom(definition, super.getDefaultTimeout());
boolean readOnly = definition.isReadOnly();
TransactionSynchronizationManager.setCurrentTransactionReadOnly(readOnly);

View File

@@ -64,9 +64,10 @@ public final class Neo4jTransactionUtils {
* {@link TransactionDefinition#PROPAGATION_REQUIRED propagation required} behaviour are supported.
*
* @param definition The transaction definition passed to a Neo4j transaction manager
* @param defaultTxManagerTimeout Default timeout from the tx manager (if available, if not, use something negative)
* @return A Neo4j native transaction configuration
*/
static TransactionConfig createTransactionConfigFrom(TransactionDefinition definition) {
static TransactionConfig createTransactionConfigFrom(TransactionDefinition definition, int defaultTxManagerTimeout) {
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
throw new InvalidIsolationLevelException(
@@ -83,6 +84,8 @@ public final class Neo4jTransactionUtils {
TransactionConfig.Builder builder = TransactionConfig.builder();
if (definition.getTimeout() > 0) {
builder = builder.withTimeout(Duration.ofSeconds(definition.getTimeout()));
} else if (defaultTxManagerTimeout > 0) {
builder = builder.withTimeout(Duration.ofSeconds(defaultTxManagerTimeout));
}
return builder.build();

View File

@@ -146,7 +146,7 @@ public class ReactiveNeo4jTransactionManager extends AbstractReactiveTransaction
return Mono.defer(() -> {
ReactiveNeo4jTransactionObject transactionObject = extractNeo4jTransaction(transaction);
TransactionConfig transactionConfig = Neo4jTransactionUtils.createTransactionConfigFrom(transactionDefinition);
TransactionConfig transactionConfig = Neo4jTransactionUtils.createTransactionConfigFrom(transactionDefinition, -1);
boolean readOnly = transactionDefinition.isReadOnly();
transactionSynchronizationManager.setCurrentTransactionReadOnly(readOnly);

View File

@@ -15,14 +15,22 @@
*/
package org.springframework.data.neo4j.core.transaction;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.neo4j.driver.TransactionConfig;
import org.springframework.transaction.support.DefaultTransactionDefinition;
/**
* @author Michael J. Simons
@@ -49,4 +57,32 @@ class Neo4jTransactionUtilsTest {
}
}
@ParameterizedTest // GH-2463
@ValueSource(ints = { Integer.MIN_VALUE, -1, 0, DefaultTransactionDefinition.TIMEOUT_DEFAULT })
void shouldNotApplyNegativeOrZeroTimeOuts(int value) {
DefaultTransactionDefinition springDef = new DefaultTransactionDefinition();
springDef.setTimeout(DefaultTransactionDefinition.TIMEOUT_DEFAULT);
TransactionConfig driverConfig = Neo4jTransactionUtils.createTransactionConfigFrom(springDef, value);
assertThat(driverConfig.timeout()).isNull();
}
@ParameterizedTest // GH-2463
@ValueSource(ints = { Integer.MIN_VALUE, -1, 0 })
void shouldPreferTxDef(int value) {
DefaultTransactionDefinition springDef = new DefaultTransactionDefinition();
springDef.setTimeout(2);
TransactionConfig driverConfig = Neo4jTransactionUtils.createTransactionConfigFrom(springDef, value);
assertThat(driverConfig.timeout()).isEqualTo(Duration.ofSeconds(2));
}
@Test // GH-2463
void shouldFallbackToTxManagerDefault() {
DefaultTransactionDefinition springDef = new DefaultTransactionDefinition();
springDef.setTimeout(DefaultTransactionDefinition.TIMEOUT_DEFAULT);
TransactionConfig driverConfig = Neo4jTransactionUtils.createTransactionConfigFrom(springDef, 3);
assertThat(driverConfig.timeout()).isEqualTo(Duration.ofSeconds(3));
}
}