public void append( TransactionRepresentation transaction, long transactionId ) throws IOException { writer.writeStartEntry( transaction.getMasterId(), transaction.getAuthorId(), transaction.getTimeStarted(), transaction.getLatestCommittedTxWhenStarted(), transaction.additionalHeader() ); // Write all the commands to the log channel writer.serialize( transaction ); // Write commit record writer.writeCommitEntry( transactionId, transaction.getTimeCommitted() ); }
checksum( transaction.additionalHeader(), transaction.getMasterId(), transaction.getAuthorId() ); transactionMetadataCache .cacheTransactionMetadata( transactionId, logPositionBeforeCommit, transaction.getMasterId(), transaction.getAuthorId(), transactionChecksum, transaction.getTimeCommitted() ); transaction.accept( indexCommandDetector ); boolean hasExplicitIndexChanges = indexCommandDetector.hasWrittenAnyExplicitIndexCommand(); if ( hasExplicitIndexChanges ) transaction.getTimeCommitted(), logPositionAfterCommit, transactionIdStore );
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; }
assertEquals( 5L, commitProcess.transaction.getLatestCommittedTxWhenStarted() ); assertEquals( startingTime, commitProcess.transaction.getTimeStarted() ); assertEquals( startingTime + 5, commitProcess.transaction.getTimeCommitted() );
private TransactionToApply mockedTransaction() { TransactionRepresentation transaction = mock( TransactionRepresentation.class ); when( transaction.additionalHeader() ).thenReturn( new byte[0] ); return new TransactionToApply( transaction ); } }
@Override public boolean accept( Visitor<StorageCommand,IOException> visitor ) throws IOException { return transactionRepresentation.accept( visitor ); }
int txLockSessionId = tx.getLockSessionId(); transaction.onClose( txId -> if ( tx.getLatestCommittedTxWhenStarted() >= txId ) format( "Out of order transaction. Expected that %d < %d", tx.getLatestCommittedTxWhenStarted(), txId ) );
private boolean batchSizeExceedsSafeZone( TransactionToApply first, TransactionToApply last ) { long lastAppliedTimestamp = last.transactionRepresentation().getTimeCommitted(); long firstAppliedTimestamp = first.transactionRepresentation().getTimeCommitted(); long chunkLength = lastAppliedTimestamp - firstAppliedTimestamp; return chunkLength > idReuseSafeZoneTime; }
int txLockSessionId = tx.getLockSessionId();
when( transaction.additionalHeader() ).thenReturn( new byte[0] ); try
public void serialize( TransactionRepresentation tx ) throws IOException { tx.accept( serializer ); }
private void markUnsafeTransactionsForTermination( TransactionToApply first, TransactionToApply last ) long firstCommittedTimestamp = first.transactionRepresentation().getTimeCommitted(); long lastCommittedTimestamp = last.transactionRepresentation().getTimeCommitted(); long earliestSafeTimestamp = lastCommittedTimestamp - idReuseSafeZoneTime;
@Override public String toString() { TransactionRepresentation tr = this.transactionRepresentation; return "Transaction #" + transactionId + (logPosition != null ? " at log position " + logPosition : " (no log position)") + " {started " + date( tr.getTimeStarted() ) + ", committed " + date( tr.getTimeCommitted() ) + ", with " + countCommands() + " commands in this transaction" + ", authored by " + tr.getAuthorId() + ", with master id " + tr.getMasterId() + ", lock session " + tr.getLockSessionId() + ", latest committed transaction id when started was " + tr.getLatestCommittedTxWhenStarted() + ", additional header bytes: " + HexPrinter.hex( tr.additionalHeader(), Integer.MAX_VALUE, "" ) + "}"; }
checksum( transaction.additionalHeader(), transaction.getMasterId(), transaction.getAuthorId() ); transactionMetadataCache .cacheTransactionMetadata( transactionId, logPositionBeforeCommit, transaction.getMasterId(), transaction.getAuthorId(), transactionChecksum, transaction.getTimeCommitted() ); transaction.accept( indexCommandDetector ); boolean hasExplicitIndexChanges = indexCommandDetector.hasWrittenAnyExplicitIndexCommand(); if ( hasExplicitIndexChanges ) transaction.getTimeCommitted(), logPositionAfterCommit, transactionIdStore );
when( transaction.additionalHeader() ).thenReturn( new byte[0] ); try
public void accept( Visitor<StorageCommand, IOException> visitor ) throws IOException { transactionRepresentation.accept( visitor ); }
@Override public boolean visit( CommittedTransactionRepresentation tx ) { TransactionRepresentation transaction = tx.getTransactionRepresentation(); assertArrayEquals( additionalHeader, transaction.additionalHeader() ); assertEquals( masterId, transaction.getMasterId() ); assertEquals( authorId, transaction.getAuthorId() ); assertEquals( timeStarted, transaction.getTimeStarted() ); assertEquals( timeCommitted, transaction.getTimeCommitted() ); assertEquals( latestCommittedTxWhenStarted, transaction.getLatestCommittedTxWhenStarted() ); visitedTransactions++; return false; }
@Test public void shouldIncludeRandomBytesInAdditionalHeader() throws Throwable { // Given TransactionRepresentation[] transactionRepresentation = new TransactionRepresentation[1]; KernelTransactions registry = newKernelTransactions( newRememberingCommitProcess( transactionRepresentation ) ); // When try ( KernelTransaction transaction = getKernelTransaction( registry ) ) { // Just pick anything that can flag that changes have been made to this transaction ((KernelTransactionImplementation) transaction).txState().nodeDoCreate( 0 ); transaction.success(); } // Then byte[] additionalHeader = transactionRepresentation[0].additionalHeader(); assertNotNull( additionalHeader ); assertTrue( additionalHeader.length > 0 ); }
private static int findCutoffIndex( Collection<TransactionRepresentation> transactions ) throws IOException { Iterator<TransactionRepresentation> iterator = transactions.iterator(); for ( int i = 0; iterator.hasNext(); i++ ) { TransactionRepresentation tx = iterator.next(); CommandExtractor extractor = new CommandExtractor(); tx.accept( extractor ); List<StorageCommand> commands = extractor.getCommands(); List<StorageCommand> nodeCommands = commands.stream() .filter( command -> command instanceof NodeCommand ).collect( toList() ); if ( nodeCommands.size() == 1 ) { return i; } } throw new AssertionError( "Couldn't find the transaction which would be the cut-off point" ); }
@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() ); } }