@Override public synchronized void run() { long now = clock.millis(); Set<KernelTransactionHandle> activeTransactions = kernelTransactions.activeTransactions(); checkExpiredTransactions( activeTransactions, now ); }
@Override public void stop() { blockNewTransactions(); stopped = true; }
@Override public void start() { stopped = false; unblockNewTransactions(); }
@Test public void startNewTransactionOnRestartedKErnelTransactions() throws Throwable { KernelTransactions kernelTransactions = newKernelTransactions(); kernelTransactions.stop(); kernelTransactions.start(); assertNotNull( "New transaction created by restarted kernel transactions component.", kernelTransactions.newInstance( KernelTransaction.Type.explicit, AUTH_DISABLED, 0L ) ); }
@Test public void shouldNotLeakTransactionOnSecurityContextFreezeFailure() throws Throwable { KernelTransactions kernelTransactions = newKernelTransactions(); LoginContext loginContext = mock( LoginContext.class ); when( loginContext.authorize( any(), any() ) ).thenThrow( new AuthorizationExpiredException( "Freeze failed." ) ); assertException(() -> kernelTransactions.newInstance(KernelTransaction.Type.explicit, loginContext, 0L), AuthorizationExpiredException.class, "Freeze failed."); assertThat("We should not have any transaction", kernelTransactions.activeTransactions(), is(empty())); }
@Test( timeout = TEST_TIMEOUT ) public void blockNewTransactions() throws Throwable { KernelTransactions kernelTransactions = newKernelTransactions(); kernelTransactions.blockNewTransactions(); Future<KernelTransaction> txOpener = t2.execute( state -> kernelTransactions.newInstance( explicit, AnonymousContext.write(), 0L ) ); t2.get().waitUntilWaiting( location -> location.isAt( KernelTransactions.class, "newInstance" ) ); assertNotDone( txOpener ); kernelTransactions.unblockNewTransactions(); assertNotNull( txOpener.get() ); }
@Test public void threadThatBlocksNewTxsCantStartNewTxs() throws Throwable { KernelTransactions kernelTransactions = newKernelTransactions(); kernelTransactions.blockNewTransactions(); try { kernelTransactions.newInstance( KernelTransaction.Type.implicit, AnonymousContext.write(), 0L ); fail( "Exception expected" ); } catch ( Exception e ) { assertThat( e, instanceOf( IllegalStateException.class ) ); } }
kernelTransactions.blockNewTransactions(); try kernelTransactions.unblockNewTransactions();
@Override public void shutdown() { disposeAll(); }
@Override public KernelTransaction beginTransaction( Transaction.Type type, LoginContext loginContext, long timeout ) throws TransactionFailureException { health.assertHealthy( TransactionFailureException.class ); KernelTransaction transaction = transactions.newInstance( type, loginContext, timeout ); transactionMonitor.transactionStarted(); return transaction; }
private static KernelTransactions createTransactions( StorageEngine storageEngine, TransactionCommitProcess commitProcess, TransactionIdStore transactionIdStore, Tracers tracers, StatementLocksFactory statementLocksFactory, StatementOperationParts statementOperations, SystemNanoClock clock, AvailabilityGuard databaseAvailabilityGuard ) { return new KernelTransactions( Config.defaults(), statementLocksFactory, null, statementOperations, null, DEFAULT, commitProcess, mock( AuxiliaryTransactionStateManager.class ), new TransactionHooks(), mock( TransactionMonitor.class ), databaseAvailabilityGuard, tracers, storageEngine, new Procedures(), transactionIdStore, clock, new AtomicReference<>( CpuClock.NOT_AVAILABLE ), new AtomicReference<>( HeapAllocation.NOT_AVAILABLE ), new CanWrite(), AutoIndexing.UNSUPPORTED, mock( ExplicitIndexStore.class ), EmptyVersionContextSupplier.EMPTY, ON_HEAP, mock( ConstraintSemantics.class ), mock( SchemaState.class ), mock( IndexingProvidersService.class), mockedTokenHolders(), DEFAULT_DATABASE_NAME, new Dependencies() ); }
@Test public void shouldTellWhenTransactionsFromSnapshotHaveBeenClosed() throws Throwable { // GIVEN KernelTransactions transactions = newKernelTransactions(); KernelTransaction a = getKernelTransaction( transactions ); KernelTransaction b = getKernelTransaction( transactions ); KernelTransaction c = getKernelTransaction( transactions ); KernelTransactionsSnapshot snapshot = transactions.get(); assertFalse( snapshot.allClosed() ); // WHEN a gets closed a.close(); assertFalse( snapshot.allClosed() ); // WHEN c gets closed and (test knowing too much) that instance getting reused in another transaction "d". c.close(); KernelTransaction d = getKernelTransaction( transactions ); assertFalse( snapshot.allClosed() ); // WHEN b finally gets closed b.close(); assertTrue( snapshot.allClosed() ); }
@Test public void incrementalUserTransactionId() throws Throwable { KernelTransactions kernelTransactions = newKernelTransactions(); try ( KernelTransaction kernelTransaction = kernelTransactions .newInstance( KernelTransaction.Type.explicit, AnonymousContext.none(), 0L ) ) { assertEquals( 1, kernelTransactions.activeTransactions().iterator().next().getUserTransactionId() ); } try ( KernelTransaction kernelTransaction = kernelTransactions .newInstance( KernelTransaction.Type.explicit, AnonymousContext.none(), 0L ) ) { assertEquals( 2, kernelTransactions.activeTransactions().iterator().next().getUserTransactionId() ); } try ( KernelTransaction kernelTransaction = kernelTransactions .newInstance( KernelTransaction.Type.explicit, AnonymousContext.none(), 0L ) ) { assertEquals( 3, kernelTransactions.activeTransactions().iterator().next().getUserTransactionId() ); } }
@Test( timeout = TEST_TIMEOUT ) public void unblockNewTransactionsFromWrongThreadThrows() throws Throwable { KernelTransactions kernelTransactions = newKernelTransactions(); kernelTransactions.blockNewTransactions(); Future<KernelTransaction> txOpener = t2.execute( state -> kernelTransactions.newInstance( explicit, AnonymousContext.write(), 0L ) ); t2.get().waitUntilWaiting( location -> location.isAt( KernelTransactions.class, "newInstance" ) ); assertNotDone( txOpener ); Future<?> wrongUnblocker = unblockTxsInSeparateThread( kernelTransactions ); try { wrongUnblocker.get(); } catch ( Exception e ) { assertThat( e, instanceOf( ExecutionException.class ) ); assertThat( e.getCause(), instanceOf( IllegalStateException.class ) ); } assertNotDone( txOpener ); kernelTransactions.unblockNewTransactions(); assertNotNull( txOpener.get() ); }
private void clearTransactions() { // We don't want to have buffered ids carry over to the new role storageEngine.clearBufferedIds(); // Get rid of all pooled transactions, as they will otherwise reference // components that have been swapped out during the mode switch. kernelModule.kernelTransactions().disposeAll(); }
private static void startAndCloseTransaction( KernelTransactions kernelTransactions ) { try { kernelTransactions.newInstance( KernelTransaction.Type.explicit, AUTH_DISABLED, 0L ).close(); } catch ( TransactionFailureException e ) { throw new RuntimeException( e ); } }
new KernelTransactions( config, statementLocksFactory, constraintIndexCreator, statementOperationParts, schemaWriteGuard, transactionHeaderInformationFactory, transactionCommitProcess, auxTxStateManager, hooks, transactionMonitor, databaseAvailabilityGuard, tracers, storageEngine, procedures, transactionIdStore, clock, cpuClockRef,
Supplier<KernelTransactionsSnapshot> transactionsSnapshotSupplier = () -> kernelModule.kernelTransactions().get(); idController.initialize( transactionsSnapshotSupplier );
@Override public KernelTransactionsSnapshot get() { return new KernelTransactionsSnapshot( activeTransactions(), clock.millis() ); }
@Test public void transactionClosesUnderlyingStoreReaderWhenDisposed() throws Throwable { StorageReader storeStatement1 = mock( StorageReader.class ); StorageReader storeStatement2 = mock( StorageReader.class ); StorageReader storeStatement3 = mock( StorageReader.class ); KernelTransactions kernelTransactions = newKernelTransactions( mock( TransactionCommitProcess.class ), storeStatement1, storeStatement2, storeStatement3 ); // start and close 3 transactions from different threads startAndCloseTransaction( kernelTransactions ); Executors.newSingleThreadExecutor().submit( () -> startAndCloseTransaction( kernelTransactions ) ).get(); Executors.newSingleThreadExecutor().submit( () -> startAndCloseTransaction( kernelTransactions ) ).get(); kernelTransactions.disposeAll(); verify( storeStatement1 ).close(); verify( storeStatement2 ).close(); verify( storeStatement3 ).close(); }