public Neo4jTransactionalContext copyFrom( GraphDatabaseQueryService graph, ThreadToStatementContextBridge txBridge, PropertyContainerLocker locker, InternalTransaction initialTransaction, Statement initialStatement, ExecutingQuery executingQuery ) { return new Neo4jTransactionalContext( graph, txBridge, locker, initialTransaction, initialStatement, executingQuery, kernel ); }
@Test public void checkKernelStatementOnCheck() { InternalTransaction initialTransaction = mock( InternalTransaction.class, new ReturnsDeepStubs() ); Kernel kernel = mock( Kernel.class ); ThreadToStatementContextBridge txBridge = mock( ThreadToStatementContextBridge.class ); KernelTransaction kernelTransaction = mockTransaction( initialStatement ); when( txBridge.getKernelTransactionBoundToThisThread( true ) ).thenReturn( kernelTransaction ); Neo4jTransactionalContext transactionalContext = new Neo4jTransactionalContext( null, txBridge, null, initialTransaction, initialStatement, null, kernel ); transactionalContext.check(); verify( kernelTransaction ).assertOpen(); }
@Test public void shouldBePossibleToTerminateWithoutActiveTransaction() { InternalTransaction tx = mock( InternalTransaction.class ); Neo4jTransactionalContext context = newContext( tx ); context.close( true ); verify( tx ).success(); verify( tx ).close(); context.terminate(); verify( tx, never() ).terminate(); }
@Test public void accumulateExecutionStatisticOverCommitAndRestart() { InternalTransaction initialTransaction = mock( InternalTransaction.class, new ReturnsDeepStubs() ); when( initialTransaction.terminationReason() ).thenReturn( Optional.empty() ); Kernel kernel = mock( Kernel.class ); Neo4jTransactionalContext transactionalContext = new Neo4jTransactionalContext( queryService, txBridge, null, initialTransaction, initialStatement, null, kernel ); statistics.setFaults( 2 ); statistics.setHits( 5 ); transactionalContext.commitAndRestartTx(); statistics.setFaults( 2 ); statistics.setHits( 5 ); transactionalContext.commitAndRestartTx(); statistics.setFaults( 2 ); statistics.setHits( 5 ); StatisticProvider statisticProvider = transactionalContext.kernelStatisticProvider(); assertEquals( "Expect to see accumulated number of page cache misses.", 6, statisticProvider.getPageCacheMisses() ); assertEquals( "Expected to see accumulated number of page cache hits.", 15, statisticProvider.getPageCacheHits() ); }
new Neo4jTransactionalContext( queryService, txBridge, locker, initialTransaction, initialStatement, executingQuery, kernel ); context.commitAndRestartTx();
@Test public void shouldThrowWhenRestartedAfterTermination() { MutableObject<Status> terminationReason = new MutableObject<>(); InternalTransaction tx = mock( InternalTransaction.class ); doAnswer( invocation -> { terminationReason.setValue( Status.Transaction.Terminated ); return null; } ).when( tx ).terminate(); when( tx.terminationReason() ).then( invocation -> Optional.ofNullable( terminationReason.getValue() ) ); Neo4jTransactionalContext context = newContext( tx ); context.terminate(); try { context.commitAndRestartTx(); fail( "Exception expected" ); } catch ( Exception e ) { assertThat( e, instanceOf( TransactionTerminatedException.class ) ); } }
@Test public void shouldThrowWhenGettingTxAfterTermination() { MutableObject<Status> terminationReason = new MutableObject<>(); InternalTransaction tx = mock( InternalTransaction.class ); doAnswer( invocation -> { terminationReason.setValue( Status.Transaction.Terminated ); return null; } ).when( tx ).terminate(); when( tx.terminationReason() ).then( invocation -> Optional.ofNullable( terminationReason.getValue() ) ); Neo4jTransactionalContext context = newContext( tx ); context.terminate(); try { context.getOrBeginNewIfClosed(); fail( "Exception expected" ); } catch ( Exception e ) { assertThat( e, instanceOf( TransactionTerminatedException.class ) ); } }
@Test public void shouldBeTopLevelWithImplicitTx() { InternalTransaction tx = mock( InternalTransaction.class ); when( tx.transactionType() ).thenReturn( KernelTransaction.Type.implicit ); Neo4jTransactionalContext context = newContext( tx ); assertTrue( context.isTopLevelTx() ); }
@Override public TransactionalContext getOrBeginNewIfClosed() { checkNotTerminated(); if ( !isOpen ) { transaction = graph.beginTransaction( transactionType, securityContext ); kernelTransaction = txBridge.getKernelTransactionBoundToThisThread( true ); statement = kernelTransaction.acquireStatement(); statement.queryRegistration().registerExecutingQuery( executingQuery ); isOpen = true; } return this; }
@Test public void shouldNotBePossibleToCloseMultipleTimes() { InternalTransaction tx = mock( InternalTransaction.class ); Neo4jTransactionalContext context = newContext( tx ); context.close( false ); context.close( true ); context.close( false ); verify( tx ).failure(); verify( tx, never() ).success(); verify( tx ).close(); }
@Test public void shouldBeOpenAfterCreation() { InternalTransaction tx = mock( InternalTransaction.class ); Neo4jTransactionalContext context = newContext( tx ); assertTrue( context.isOpen() ); }
new Neo4jTransactionalContext( queryService, txBridge, locker, initialTransaction, initialStatement, executingQuery, kernel ); context.commitAndRestartTx(); throw new AssertionError( "Expected RuntimeException to be thrown" );
@Test public void shouldNotBeTopLevelWithExplicitTx() { InternalTransaction tx = mock( InternalTransaction.class ); when( tx.transactionType() ).thenReturn( KernelTransaction.Type.explicit ); Neo4jTransactionalContext context = newContext( tx ); assertFalse( context.isTopLevelTx() ); }
@Override public TransactionalContext getOrBeginNewIfClosed() { checkNotTerminated(); if ( !isOpen ) { transaction = graph.beginTransaction( transactionType, securityContext ); kernelTransaction = txBridge.getKernelTransactionBoundToThisThread( true ); statement = kernelTransaction.acquireStatement(); statement.queryRegistration().registerExecutingQuery( executingQuery ); isOpen = true; } return this; }
public static TransactionalContextFactory create( GraphDatabaseFacade.SPI spi, ThreadToStatementContextBridge txBridge, PropertyContainerLocker locker ) { Supplier<GraphDatabaseQueryService> queryService = lazySingleton( spi::queryService ); Supplier<Kernel> kernel = lazySingleton( spi::kernel ); Neo4jTransactionalContext.Creator contextCreator = ( tx, initialStatement, executingQuery ) -> new Neo4jTransactionalContext( queryService.get(), txBridge, locker, tx, initialStatement, executingQuery, kernel.get() ); return new Neo4jTransactionalContextFactory( txBridge, contextCreator ); }
@Test public void shouldBePossibleToCloseAfterTermination() { InternalTransaction tx = mock( InternalTransaction.class ); when( tx.transactionType() ).thenReturn( KernelTransaction.Type.implicit ); Neo4jTransactionalContext context = newContext( tx ); context.terminate(); verify( tx ).terminate(); verify( tx, never() ).close(); context.close( false ); verify( tx ).failure(); verify( tx ).close(); }
@Deprecated public static TransactionalContextFactory create( GraphDatabaseQueryService queryService, PropertyContainerLocker locker ) { DependencyResolver resolver = queryService.getDependencyResolver(); ThreadToStatementContextBridge txBridge = resolver.resolveDependency( ThreadToStatementContextBridge.class ); Kernel kernel = resolver.resolveDependency( Kernel.class ); Neo4jTransactionalContext.Creator contextCreator = ( tx, initialStatement, executingQuery ) -> new Neo4jTransactionalContext( queryService, txBridge, locker, tx, initialStatement, executingQuery, kernel ); return new Neo4jTransactionalContextFactory( txBridge, contextCreator ); }
private Neo4jTransactionalContext newContext( InternalTransaction initialTx ) { return new Neo4jTransactionalContext( queryService, txBridge, new PropertyContainerLocker(), initialTx, initialStatement, null, null ); }