private TransactionToApply mockedTransaction() { TransactionRepresentation transaction = mock( TransactionRepresentation.class ); when( transaction.additionalHeader() ).thenReturn( new byte[0] ); return new TransactionToApply( transaction ); } }
private void apply( BatchTransactionApplier applier, TransactionRepresentation transaction ) throws Exception { CommandHandlerContract.apply( applier, new TransactionToApply( transaction ) ); }
private static TransactionToApply toApply( Collection<TransactionRepresentation> transactions ) { TransactionToApply first = null; TransactionToApply last = null; for ( TransactionRepresentation transactionRepresentation : transactions ) { TransactionToApply transaction = new TransactionToApply( transactionRepresentation ); if ( first == null ) { first = last = transaction; } else { last.next( transaction ); last = transaction; } } return first; }
private TransactionToApply batchOf( TransactionRepresentation... transactions ) { TransactionToApply first = null; TransactionToApply last = null; for ( TransactionRepresentation transaction : transactions ) { TransactionToApply tx = new TransactionToApply( transaction ); if ( first == null ) { first = last = tx; } else { last.next( tx ); last = tx; } } return first; } }
private static TransactionToApply newTransactionThatFailsWith( Exception error ) throws IOException { TransactionRepresentation transaction = mock( TransactionRepresentation.class ); when( transaction.additionalHeader() ).thenReturn( new byte[0] ); // allow to build validated index updates but fail on actual tx application doThrow( error ).when( transaction ).accept( any() ); long txId = ThreadLocalRandom.current().nextLong( 0, 1000 ); TransactionToApply txToApply = new TransactionToApply( transaction ); FakeCommitment commitment = new FakeCommitment( txId, mock( TransactionIdStore.class ) ); commitment.setHasExplicitIndexChanges( false ); txToApply.commitment( commitment, txId ); return txToApply; }
private static TransactionToApply tx( Collection<StorageCommand> commands ) { TransactionToApply tx = new TransactionToApply( transactionRepresentation( commands ) ); tx.commitment( NO_COMMITMENT, 0 ); return tx; }
private void visitSchemaRuleCommand( BatchTransactionApplier applier, SchemaRuleCommand command ) throws Exception { TransactionToApply tx = new TransactionToApply( new PhysicalTransactionRepresentation( singletonList( command ) ), txId ); CommandHandlerContract.apply( applier, tx ); } }
private void applyExternalTransaction( long transactionId, Command...commands ) throws Exception { LockService lockService = mock( LockService.class ); when( lockService.acquireNodeLock( anyLong(), any(LockService.LockType.class) )).thenReturn( LockService.NO_LOCK ); when( lockService.acquireRelationshipLock( anyLong(), any(LockService.LockType.class) )).thenReturn( LockService.NO_LOCK ); NeoStoreBatchTransactionApplier applier = new NeoStoreBatchTransactionApplier( neoStores, mock( CacheAccessBackDoor.class ), lockService ); TransactionRepresentation tx = new PhysicalTransactionRepresentation( Arrays.asList( commands ) ); CommandHandlerContract.apply( applier, txApplier -> { tx.accept( txApplier ); return false; }, new TransactionToApply( tx, transactionId ) ); }
private static TransactionToApply prepareTransaction() { List<StorageCommand> commands = createCommands(); PhysicalTransactionRepresentation transactionRepresentation = new PhysicalTransactionRepresentation( commands ); transactionRepresentation.setHeader( new byte[0], 0, 0, 0, 0, 0, 0 ); return new TransactionToApply( transactionRepresentation ); }
@Test public void shouldNotifyCacheAccessOnHowManyUpdatesOnCountsWeHadSoFar() throws Exception { // GIVEN final CountsTracker tracker = mock( CountsTracker.class ); final CountsAccessor.Updater updater = mock( CountsAccessor.Updater.class ); when( tracker.apply( anyLong() ) ).thenReturn( Optional.of( updater ) ); final CountsStoreBatchTransactionApplier applier = new CountsStoreBatchTransactionApplier( tracker, TransactionApplicationMode.INTERNAL ); // WHEN try ( TransactionApplier txApplier = applier.startTx( new TransactionToApply( null, 2L ) ) ) { txApplier.visitNodeCountsCommand( new Command.NodeCountsCommand( StatementConstants.ANY_LABEL, 1 ) ); } // THEN verify( updater, times( 1 ) ).incrementNodeCount( StatementConstants.ANY_LABEL, 1 ); } }
@Test public void shouldLinkTogetherTransactions() throws Exception { // GIVEN Applier applier = mock( Applier.class ); int batchSize = 10; TransactionQueue queue = new TransactionQueue( batchSize, applier ); // WHEN TransactionToApply[] txs = new TransactionToApply[batchSize]; for ( int i = 0; i < batchSize; i++ ) { queue.queue( txs[i] = new TransactionToApply( mock( TransactionRepresentation.class ) ) ); } // THEN verify( applier, times( 1 ) ).apply( any(), any() ); for ( int i = 0; i < txs.length - 1; i++ ) { assertEquals( txs[i + 1], txs[i].next() ); } } }
@Test public void shouldSuccessfullyCommitTransactionWithNoCommands() throws Exception { // GIVEN long txId = 11; long commitTimestamp = System.currentTimeMillis(); TransactionIdStore transactionIdStore = mock( TransactionIdStore.class ); TransactionAppender appender = new TestableTransactionAppender( transactionIdStore ); when( transactionIdStore.nextCommittingTransactionId() ).thenReturn( txId ); StorageEngine storageEngine = mock( StorageEngine.class ); TransactionCommitProcess commitProcess = new TransactionRepresentationCommitProcess( appender, storageEngine ); PhysicalTransactionRepresentation noCommandTx = new PhysicalTransactionRepresentation( Collections.emptyList() ); noCommandTx.setHeader( new byte[0], -1, -1, -1, -1, -1, -1 ); // WHEN commitProcess.commit( new TransactionToApply( noCommandTx ), commitEvent, INTERNAL ); verify( transactionIdStore ).transactionCommitted( txId, FakeCommitment.CHECKSUM, FakeCommitment.TIMESTAMP ); }
@Override public boolean visit( CommittedTransactionRepresentation transaction ) throws Exception { TransactionRepresentation txRepresentation = transaction.getTransactionRepresentation(); long txId = transaction.getCommitEntry().getTxId(); TransactionToApply tx = new TransactionToApply( txRepresentation, txId ); tx.commitment( NO_COMMITMENT, txId ); tx.logPosition( transaction.getStartEntry().getStartPosition() ); storageEngine.apply( tx, mode ); return false; }
@Test public void shouldKernelPanicIfTransactionIdsMismatch() throws Throwable { // Given BatchingTransactionAppender appender = life.add( createTransactionAppender() ); when( transactionIdStore.nextCommittingTransactionId() ).thenReturn( 42L ); TransactionToApply batch = new TransactionToApply( mock( TransactionRepresentation.class ), 43L ); // When try { appender.append( batch, LogAppendEvent.NULL ); fail( "should have thrown " ); } catch ( IllegalStateException ex ) { // Then verify( databaseHealth, times( 1 ) ).panic( ex ); } }
private Future<Object> applyInT2( GraphDatabaseAPI db, List<TransactionRepresentation> transactions ) { TransactionCommitProcess commitProcess = db.getDependencyResolver().resolveDependency( TransactionCommitProcess.class ); return t2.execute( state -> { transactions.forEach( tx -> { try { // It will matter if the transactions are supplied all in the same batch or one by one // since the CountsTracker#apply lock is held and released per transaction commitProcess.commit( new TransactionToApply( tx ), NULL, EXTERNAL ); } catch ( TransactionFailureException e ) { throw new RuntimeException( e ); } } ); return null; } ); }
public void apply( Transaction transaction ) throws TransactionFailureException { TransactionRepresentation representation = transaction.representation( idGenerator(), masterId(), myId(), transactionIdStore.getLastCommittedTransactionId(), neoStores ); commitProcess.commit( new TransactionToApply( representation ), CommitEvent.NULL, TransactionApplicationMode.EXTERNAL ); }
protected TransactionToApply tx() { NodeRecord before = new NodeRecord( 0 ); NodeRecord after = new NodeRecord( 0 ); after.setInUse( true ); Command.NodeCommand nodeCommand = new Command.NodeCommand( before, after ); PhysicalTransactionRepresentation tx = new PhysicalTransactionRepresentation( singletonList( nodeCommand ) ); tx.setHeader( new byte[0], 0, 0, 0, 0, 0, 0 ); return new TransactionToApply( tx ); }
TransactionToApply nextTransaction( long txId ) { PhysicalTransactionRepresentation representation = new PhysicalTransactionRepresentation( createRandomCommands() ); TransactionHeaderInformation headerInfo = DEFAULT.create(); representation.setHeader( headerInfo.getAdditionalHeader(), headerInfo.getMasterId(), headerInfo.getAuthorId(), headerInfo.getAuthorId(), txId, currentTimeMillis(), 42 ); return new TransactionToApply( representation ); }
private void addATransactionAndRewind( LifeSupport life, LogFiles logFiles, TransactionMetadataCache positionCache, TransactionIdStore transactionIdStore, byte[] additionalHeader, int masterId, int authorId, long timeStarted, long latestCommittedTxWhenStarted, long timeCommitted ) throws IOException { TransactionAppender appender = life.add( new BatchingTransactionAppender( logFiles, NO_ROTATION, positionCache, transactionIdStore, BYPASS, DATABASE_HEALTH ) ); PhysicalTransactionRepresentation transaction = new PhysicalTransactionRepresentation( singleCreateNodeCommand() ); transaction.setHeader( additionalHeader, masterId, authorId, timeStarted, latestCommittedTxWhenStarted, timeCommitted, -1 ); appender.append( new TransactionToApply( transaction ), LogAppendEvent.NULL ); }
@Test public void shouldAppendSingleTransaction() throws Exception { // GIVEN when( logFile.getWriter() ).thenReturn( channel ); long txId = 15; when( transactionIdStore.nextCommittingTransactionId() ).thenReturn( txId ); TransactionAppender appender = life.add( createTransactionAppender() ); // WHEN TransactionRepresentation transaction = transaction( singleCreateNodeCommand( 0 ), new byte[]{1, 2, 5}, 2, 1, 12345, 4545, 12345 + 10 ); appender.append( new TransactionToApply( transaction ), logAppendEvent ); // THEN final LogEntryReader<ReadableLogChannel> logEntryReader = new VersionAwareLogEntryReader<>(); try ( PhysicalTransactionCursor<ReadableLogChannel> reader = new PhysicalTransactionCursor<>( channel, logEntryReader ) ) { reader.next(); TransactionRepresentation tx = reader.get().getTransactionRepresentation(); assertArrayEquals( transaction.additionalHeader(), tx.additionalHeader() ); assertEquals( transaction.getMasterId(), tx.getMasterId() ); assertEquals( transaction.getAuthorId(), tx.getAuthorId() ); assertEquals( transaction.getTimeStarted(), tx.getTimeStarted() ); assertEquals( transaction.getTimeCommitted(), tx.getTimeCommitted() ); assertEquals( transaction.getLatestCommittedTxWhenStarted(), tx.getLatestCommittedTxWhenStarted() ); } }