use of org.neo4j.kernel.api.QueryRegistry in project neo4j by neo4j.
the class QueryTracingIT method chainedQueryExecution.
@Test
void chainedQueryExecution() {
try (var transaction = databaseAPI.beginTransaction(IMPLICIT, AUTH_DISABLED);
var statement = (KernelStatement) transaction.kernelTransaction().acquireStatement()) {
QueryRegistry queryRegistry = statement.queryRegistration();
assertTrue(queryRegistry.executingQuery().isEmpty());
assertThat(queries).isEmpty();
var outerQuery = "CALL db.testCaptureProcedure()";
var innerQuery = "match (n) return count(n)";
try (Result result = transaction.execute(outerQuery)) {
result.next();
}
assertThat(queries).hasSize(3);
assertThat(queries.get(0).rawQueryText()).isEqualTo(outerQuery);
assertThat(queries.get(1).rawQueryText()).isEqualTo(innerQuery);
assertThat(queries.get(2).rawQueryText()).isEqualTo(outerQuery);
}
}
use of org.neo4j.kernel.api.QueryRegistry in project neo4j by neo4j.
the class Neo4jTransactionalContextTest method rollsBackNewlyCreatedTransactionIfTerminationDetectedOnCloseDuringPeriodicCommit.
@SuppressWarnings("ConstantConditions")
@Test
void rollsBackNewlyCreatedTransactionIfTerminationDetectedOnCloseDuringPeriodicCommit() throws TransactionFailureException {
// Given
InternalTransaction userTransaction = mock(InternalTransaction.class, new ReturnsDeepStubs());
KernelTransaction.Type transactionType = KernelTransaction.Type.IMPLICIT;
SecurityContext securityContext = SecurityContext.AUTH_DISABLED;
ClientConnectionInfo connectionInfo = ClientConnectionInfo.EMBEDDED_CONNECTION;
when(userTransaction.transactionType()).thenReturn(transactionType);
when(userTransaction.clientInfo()).thenReturn(connectionInfo);
when(userTransaction.securityContext()).thenReturn(securityContext);
when(userTransaction.terminationReason()).thenReturn(Optional.empty());
GraphDatabaseQueryService queryService = mock(GraphDatabaseQueryService.class);
KernelStatement initialStatement = mock(KernelStatement.class);
KernelTransaction initialKTX = mockTransaction(initialStatement);
QueryRegistry initialQueryRegistry = mock(QueryRegistry.class);
ExecutingQuery executingQuery = mock(ExecutingQuery.class);
KernelStatement secondStatement = mock(KernelStatement.class);
KernelTransaction secondKTX = mockTransaction(secondStatement);
QueryRegistry secondQueryRegistry = mock(QueryRegistry.class);
when(transactionFactory.beginKernelTransaction(transactionType, securityContext, connectionInfo)).thenReturn(secondKTX);
when(executingQuery.databaseId()).thenReturn(Optional.of(namedDatabaseId));
Mockito.doThrow(RuntimeException.class).when(initialKTX).commit();
when(initialStatement.queryRegistration()).thenReturn(initialQueryRegistry);
when(userTransaction.kernelTransaction()).thenReturn(initialKTX, initialKTX, secondKTX);
when(secondStatement.queryRegistration()).thenReturn(secondQueryRegistry);
Neo4jTransactionalContext context = new Neo4jTransactionalContext(queryService, userTransaction, initialStatement, executingQuery, transactionFactory);
// When
assertThrows(RuntimeException.class, context::commitAndRestartTx);
Object[] mocks = { userTransaction, initialQueryRegistry, initialKTX, secondQueryRegistry, secondKTX };
InOrder order = Mockito.inOrder(mocks);
// (0) Constructor
order.verify(userTransaction).transactionType();
order.verify(userTransaction).securityContext();
order.verify(userTransaction).clientInfo();
// not terminated check
order.verify(userTransaction).terminationReason();
// (1) Collect statistics
order.verify(initialKTX).executionStatistics();
// (3) Register new
order.verify(secondKTX).acquireStatement();
order.verify(secondQueryRegistry).registerExecutingQuery(executingQuery);
// (4) Unregister, and close old
order.verify(initialQueryRegistry).unregisterExecutingQuery(executingQuery);
order.verify(userTransaction).rollback();
}
use of org.neo4j.kernel.api.QueryRegistry in project neo4j by neo4j.
the class Neo4jTransactionalContextTest method neverStopsExecutingQueryDuringCommitAndRestartTx.
@Test
void neverStopsExecutingQueryDuringCommitAndRestartTx() throws TransactionFailureException {
// Given
KernelTransaction initialKTX = mockTransaction(statement);
InternalTransaction userTransaction = mock(InternalTransaction.class, new ReturnsDeepStubs());
KernelTransaction.Type transactionType = KernelTransaction.Type.IMPLICIT;
SecurityContext securityContext = SecurityContext.AUTH_DISABLED;
ClientConnectionInfo connectionInfo = ClientConnectionInfo.EMBEDDED_CONNECTION;
when(userTransaction.transactionType()).thenReturn(transactionType);
when(userTransaction.securityContext()).thenReturn(securityContext);
when(userTransaction.terminationReason()).thenReturn(Optional.empty());
when(userTransaction.clientInfo()).thenReturn(connectionInfo);
QueryRegistry initialQueryRegistry = mock(QueryRegistry.class);
ExecutingQuery executingQuery = mock(ExecutingQuery.class);
KernelStatement secondStatement = mock(KernelStatement.class);
KernelTransaction secondKTX = mockTransaction(secondStatement);
QueryRegistry secondQueryRegistry = mock(QueryRegistry.class);
when(transactionFactory.beginKernelTransaction(transactionType, securityContext, connectionInfo)).thenReturn(secondKTX);
when(executingQuery.databaseId()).thenReturn(Optional.of(namedDatabaseId));
when(statement.queryRegistration()).thenReturn(initialQueryRegistry);
when(userTransaction.kernelTransaction()).thenReturn(initialKTX, initialKTX, secondKTX);
when(secondStatement.queryRegistration()).thenReturn(secondQueryRegistry);
Neo4jTransactionalContext context = new Neo4jTransactionalContext(queryService, userTransaction, statement, executingQuery, transactionFactory);
// When
context.commitAndRestartTx();
// Then
Object[] mocks = { userTransaction, initialKTX, initialQueryRegistry, secondQueryRegistry, secondKTX };
InOrder order = Mockito.inOrder(mocks);
// (0) Constructor
order.verify(userTransaction).transactionType();
order.verify(userTransaction).securityContext();
order.verify(userTransaction).clientInfo();
// not terminated check
order.verify(userTransaction).terminationReason();
// (1) Collect stats
order.verify(initialKTX).executionStatistics();
// (3) Register new
order.verify(secondKTX).acquireStatement();
order.verify(secondQueryRegistry).registerExecutingQuery(executingQuery);
// (4) Unregister, and close old
order.verify(initialQueryRegistry).unregisterExecutingQuery(executingQuery);
order.verify(initialKTX).commit();
}
use of org.neo4j.kernel.api.QueryRegistry in project neo4j by neo4j.
the class Neo4jTransactionalContext method commitAndRestartTx.
@Override
public long commitAndRestartTx() {
/*
* This method is use by the Cypher runtime to cater for PERIODIC COMMIT, which allows a single query to
* periodically, after x number of rows, to commit a transaction and spawn a new one.
*
* To still keep track of the running stream after switching transactions, we need to open the new transaction
* before closing the old one. This way, a query will not disappear and appear when switching transactions.
*
* Since our transactions are thread bound, we must first unbind the old transaction from the thread before
* creating a new one. And then we need to do that thread switching again to close the old transaction.
*/
checkNotTerminated();
collectTransactionExecutionStatistic();
// (1) Remember old statement
QueryRegistry oldQueryRegistry = statement.queryRegistration();
Statement oldStatement = statement;
KernelTransaction oldKernelTx = transaction.kernelTransaction();
// (2) Create and register new transaction
kernelTransaction = transactionFactory.beginKernelTransaction(transactionType, securityContext, clientInfo);
statement = (KernelStatement) kernelTransaction.acquireStatement();
statement.queryRegistration().registerExecutingQuery(executingQuery);
transaction.setTransaction(kernelTransaction);
// (3) Commit and close old transaction (and unregister as a side effect of that)
oldQueryRegistry.unregisterExecutingQuery(executingQuery);
try {
oldStatement.close();
return oldKernelTx.commit();
} catch (Throwable t) {
// Corner case: The old transaction might have been terminated by the user. Now we also need to
// terminate the new transaction.
transaction.rollback();
throw new RuntimeException(t);
}
}
use of org.neo4j.kernel.api.QueryRegistry in project neo4j by neo4j.
the class Neo4jTransactionalContextTest method setUpMocks.
private void setUpMocks() {
queryService = mock(GraphDatabaseQueryService.class);
DependencyResolver resolver = mock(DependencyResolver.class);
statement = mock(KernelStatement.class);
statistics = new ConfiguredExecutionStatistics();
QueryRegistry queryRegistry = mock(QueryRegistry.class);
InternalTransaction internalTransaction = mock(InternalTransaction.class);
when(internalTransaction.terminationReason()).thenReturn(Optional.empty());
when(statement.queryRegistration()).thenReturn(queryRegistry);
when(queryService.getDependencyResolver()).thenReturn(resolver);
when(queryService.beginTransaction(any(), any(), any())).thenReturn(internalTransaction);
KernelTransaction mockTransaction = mockTransaction(statement);
}
Aggregations