Add additional testscenarios for transaction management.
This commit is contained in:
@@ -38,11 +38,11 @@ public class Neo4jResourceHolder extends ResourceHolderSupport {
|
||||
|
||||
private final Transaction transaction;
|
||||
|
||||
public Neo4jResourceHolder(Session session) {
|
||||
Neo4jResourceHolder(Session session) {
|
||||
this(session, TransactionConfig.empty());
|
||||
}
|
||||
|
||||
public Neo4jResourceHolder(Session session, TransactionConfig transactionConfig) {
|
||||
Neo4jResourceHolder(Session session, TransactionConfig transactionConfig) {
|
||||
this.session = session;
|
||||
|
||||
this.transaction = this.session.beginTransaction(transactionConfig);
|
||||
@@ -52,7 +52,7 @@ public class Neo4jResourceHolder extends ResourceHolderSupport {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
void commit() {
|
||||
|
||||
Assert.state(hasActiveTransaction(), "Transaction must be open, but has already been closed.");
|
||||
Assert.state(!isRollbackOnly(), "Resource msut not be marked as rollback only.");
|
||||
@@ -61,7 +61,7 @@ public class Neo4jResourceHolder extends ResourceHolderSupport {
|
||||
transaction.close();
|
||||
}
|
||||
|
||||
public void rollback() {
|
||||
void rollback() {
|
||||
|
||||
Assert.state(hasActiveTransaction(), "Transaction must be open, but has already been closed.");
|
||||
|
||||
@@ -69,7 +69,7 @@ public class Neo4jResourceHolder extends ResourceHolderSupport {
|
||||
transaction.close();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
void close() {
|
||||
|
||||
Assert.state(hasActiveSession(), "Session must be open, but has already been closed.");
|
||||
|
||||
@@ -90,12 +90,12 @@ public class Neo4jResourceHolder extends ResourceHolderSupport {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean hasActiveSession() {
|
||||
boolean hasActiveSession() {
|
||||
|
||||
return session.isOpen();
|
||||
}
|
||||
|
||||
public boolean hasActiveTransaction() {
|
||||
boolean hasActiveTransaction() {
|
||||
|
||||
return transaction.isOpen();
|
||||
}
|
||||
|
||||
@@ -89,8 +89,7 @@ public class Neo4jTransactionManager extends AbstractPlatformTransactionManager
|
||||
resourceHolder.setSynchronizedWithTransaction(true);
|
||||
TransactionSynchronizationManager.bindResource(driver, resourceHolder);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
throw new TransactionSystemException(String.format("Could not open a new Neo4j session:", ex));
|
||||
throw new TransactionSystemException(String.format("Could not open a new Neo4j session: %s", ex.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.neo4j.driver.v1.AccessMode;
|
||||
import org.neo4j.driver.v1.Driver;
|
||||
import org.neo4j.driver.v1.Session;
|
||||
@@ -51,6 +53,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||
* @author Michael J. Simons
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
class DefaultNeo4jStatementRunnerSupplierTest {
|
||||
|
||||
@Mock
|
||||
@@ -68,6 +71,7 @@ class DefaultNeo4jStatementRunnerSupplierTest {
|
||||
AtomicBoolean sessionIsOpen = new AtomicBoolean(true);
|
||||
AtomicBoolean transactionIsOpen = new AtomicBoolean(true);
|
||||
|
||||
when(driver.session()).thenReturn(session);
|
||||
when(driver.session(AccessMode.WRITE, Collections.emptyList())).thenReturn(session);
|
||||
|
||||
when(session.beginTransaction(any(TransactionConfig.class))).thenReturn(transaction);
|
||||
@@ -84,6 +88,100 @@ class DefaultNeo4jStatementRunnerSupplierTest {
|
||||
when(transaction.isOpen()).thenAnswer(invocation -> transactionIsOpen.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithoutSynchronizations() {
|
||||
StatementRunnerSupplier<StatementRunner> statementRunnerSupplier = new DefaultNeo4jStatementRunnerSupplier(
|
||||
driver);
|
||||
|
||||
@SuppressWarnings({ "unused" })
|
||||
StatementRunner statementRunner = statementRunnerSupplier.get();
|
||||
|
||||
verify(driver).session();
|
||||
verifyNoMoreInteractions(driver, session, transaction);
|
||||
}
|
||||
|
||||
@Nested
|
||||
class BasedOnNeo4jTransactions {
|
||||
@Test
|
||||
void shouldOpenNewTransaction() {
|
||||
|
||||
Neo4jTransactionManager txManager = new Neo4jTransactionManager(driver);
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(txManager);
|
||||
StatementRunnerSupplier<StatementRunner> statementRunnerSupplier = new DefaultNeo4jStatementRunnerSupplier(
|
||||
driver);
|
||||
|
||||
txTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
|
||||
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
assertThat(transactionStatus.isNewTransaction()).isTrue();
|
||||
assertThat(TransactionSynchronizationManager.hasResource(driver)).isTrue();
|
||||
|
||||
@SuppressWarnings({ "unused" })
|
||||
StatementRunner statementRunner = statementRunnerSupplier.get();
|
||||
|
||||
transactionStatus.setRollbackOnly();
|
||||
}
|
||||
});
|
||||
|
||||
verify(driver).session(AccessMode.WRITE, Collections.emptyList());
|
||||
|
||||
verify(session).isOpen();
|
||||
verify(session).beginTransaction(any(TransactionConfig.class));
|
||||
verify(session).close();
|
||||
|
||||
verify(transaction, times(2)).isOpen();
|
||||
verify(transaction).failure();
|
||||
verify(transaction).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldParticipateInOngoingTransaction() {
|
||||
|
||||
Neo4jTransactionManager txManager = new Neo4jTransactionManager(driver);
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(txManager);
|
||||
StatementRunnerSupplier<StatementRunner> statementRunnerSupplier = new DefaultNeo4jStatementRunnerSupplier(
|
||||
driver);
|
||||
|
||||
txTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus outerStatus) {
|
||||
|
||||
@SuppressWarnings({ "unused" })
|
||||
StatementRunner outerStatementRunner = statementRunnerSupplier.get();
|
||||
assertThat(outerStatus.isNewTransaction()).isTrue();
|
||||
|
||||
txTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus innerStatus) {
|
||||
|
||||
assertThat(innerStatus.isNewTransaction()).isFalse();
|
||||
|
||||
@SuppressWarnings({ "unused" })
|
||||
StatementRunner innerStatementRunner = statementRunnerSupplier.get();
|
||||
}
|
||||
});
|
||||
|
||||
outerStatus.setRollbackOnly();
|
||||
}
|
||||
});
|
||||
|
||||
verify(driver).session(AccessMode.WRITE, Collections.emptyList());
|
||||
|
||||
verify(session).isOpen();
|
||||
verify(session).beginTransaction(any(TransactionConfig.class));
|
||||
verify(session).close();
|
||||
|
||||
verify(transaction, times(2)).isOpen();
|
||||
verify(transaction).failure();
|
||||
verify(transaction).close();
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class BasedOnJtaTransactions {
|
||||
|
||||
@@ -107,6 +205,7 @@ class DefaultNeo4jStatementRunnerSupplierTest {
|
||||
assertThat(transactionStatus.isNewTransaction()).isTrue();
|
||||
assertThat(TransactionSynchronizationManager.hasResource(driver)).isFalse();
|
||||
|
||||
@SuppressWarnings({ "unused" })
|
||||
StatementRunner statementRunner = statementRunnerSupplier.get();
|
||||
|
||||
assertThat(TransactionSynchronizationManager.hasResource(driver)).isTrue();
|
||||
@@ -127,7 +226,7 @@ class DefaultNeo4jStatementRunnerSupplierTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldParticipateInOngoingTransactionWithRollback() throws Exception {
|
||||
void shouldParticipateInOngoingTransactionWithRollback() throws Exception {
|
||||
|
||||
when(userTransaction.getStatus()).thenReturn(Status.STATUS_NO_TRANSACTION, Status.STATUS_ACTIVE,
|
||||
Status.STATUS_ACTIVE);
|
||||
@@ -170,44 +269,6 @@ class DefaultNeo4jStatementRunnerSupplierTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class BasedOnNeo4jTransactions {
|
||||
@Test
|
||||
public void shouldParticipateInOngoingTransaction() {
|
||||
|
||||
Neo4jTransactionManager txManager = new Neo4jTransactionManager(driver);
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(txManager);
|
||||
StatementRunnerSupplier<StatementRunner> statementRunnerSupplier = new DefaultNeo4jStatementRunnerSupplier(
|
||||
driver);
|
||||
|
||||
txTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
|
||||
|
||||
assertThat(TransactionSynchronizationManager.isSynchronizationActive()).isTrue();
|
||||
assertThat(transactionStatus.isNewTransaction()).isTrue();
|
||||
assertThat(TransactionSynchronizationManager.hasResource(driver)).isTrue();
|
||||
|
||||
@SuppressWarnings({ "unused" })
|
||||
StatementRunner statementRunner = statementRunnerSupplier.get();
|
||||
|
||||
transactionStatus.setRollbackOnly();
|
||||
}
|
||||
});
|
||||
|
||||
verify(driver).session(AccessMode.WRITE, Collections.emptyList());
|
||||
|
||||
verify(session).isOpen();
|
||||
verify(session).beginTransaction(any(TransactionConfig.class));
|
||||
verify(session).close();
|
||||
|
||||
verify(transaction, times(2)).isOpen();
|
||||
verify(transaction).failure();
|
||||
verify(transaction).close();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void verifyTransactionSynchronizationManagerState() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user