//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldAppendSingleTransaction() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldAppendSingleTransaction()
        {
            // GIVEN
            when(_logFile.Writer).thenReturn(_channel);
            long txId = 15;

            when(_transactionIdStore.nextCommittingTransactionId()).thenReturn(txId);
            TransactionAppender appender = Life.add(CreateTransactionAppender());

            // WHEN
            TransactionRepresentation transaction = transaction(SingleCreateNodeCommand(0), new sbyte[] { 1, 2, 5 }, 2, 1, 12345, 4545, 12345 + 10);

            appender.Append(new TransactionToApply(transaction), _logAppendEvent);

            // THEN
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader<ReadableLogChannel> logEntryReader = new org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader<>();
            LogEntryReader <ReadableLogChannel> logEntryReader = new VersionAwareLogEntryReader <ReadableLogChannel>();

            using (PhysicalTransactionCursor <ReadableLogChannel> reader = new PhysicalTransactionCursor <ReadableLogChannel>(_channel, logEntryReader))
            {
                reader.Next();
                TransactionRepresentation tx = reader.Get().TransactionRepresentation;
                assertArrayEquals(transaction.AdditionalHeader(), tx.AdditionalHeader());
                assertEquals(transaction.MasterId, tx.MasterId);
                assertEquals(transaction.AuthorId, tx.AuthorId);
                assertEquals(transaction.TimeStarted, tx.TimeStarted);
                assertEquals(transaction.TimeCommitted, tx.TimeCommitted);
                assertEquals(transaction.LatestCommittedTxWhenStarted, tx.LatestCommittedTxWhenStarted);
            }
        }
        public override long Append(TransactionToApply batch, LogAppendEvent logAppendEvent)
        {
            long txId = TransactionIdStore_Fields.BASE_TX_ID;

            while (batch != null)
            {
                txId = _transactionIdStore.nextCommittingTransactionId();
                batch.Commitment(new FakeCommitment(txId, _transactionIdStore), txId);
                batch.Commitment().publishAsCommitted();
                batch = batch.Next();
            }
            return(txId);
        }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public long append(org.neo4j.kernel.impl.api.TransactionToApply batch, org.neo4j.kernel.impl.transaction.tracing.LogAppendEvent logAppendEvent) throws java.io.IOException
        public override long Append(TransactionToApply batch, LogAppendEvent logAppendEvent)
        {
            // Assigned base tx id just to make compiler happy
            long lastTransactionId = TransactionIdStore_Fields.BASE_TX_ID;

            // Synchronized with logFile to get absolute control over concurrent rotations happening
            lock ( _logFile )
            {
                // Assert that kernel is healthy before making any changes
                _databaseHealth.assertHealthy(typeof(IOException));
                using (SerializeTransactionEvent serialiseEvent = logAppendEvent.BeginSerializeTransaction())
                {
                    // Append all transactions in this batch to the log under the same logFile monitor
                    TransactionToApply tx = batch;
                    while (tx != null)
                    {
                        long transactionId = _transactionIdStore.nextCommittingTransactionId();

                        // If we're in a scenario where we're merely replicating transactions, i.e. transaction
                        // id have already been generated by another entity we simply check that our id
                        // that we generated match that id. If it doesn't we've run into a problem we can't ´
                        // really recover from and would point to a bug somewhere.
                        MatchAgainstExpectedTransactionIdIfAny(transactionId, tx);

                        TransactionCommitment commitment = AppendToLog(tx.TransactionRepresentation(), transactionId);
                        tx.Commitment(commitment, transactionId);
                        tx.LogPosition(commitment.LogPosition());
                        tx = tx.Next();
                        lastTransactionId = transactionId;
                    }
                }
            }

            // At this point we've appended all transactions in this batch, but we can't mark any of them
            // as committed since they haven't been forced to disk yet. So here we force, or potentially
            // piggy-back on another force, but anyway after this call below we can be sure that all our transactions
            // in this batch exist durably on disk.
            if (ForceAfterAppend(logAppendEvent))
            {
                // We got lucky and were the one forcing the log. It's enough if ones of all doing concurrent committers
                // checks the need for log rotation.
                bool logRotated = _logRotation.rotateLogIfNeeded(logAppendEvent);
                logAppendEvent.LogRotated = logRotated;
            }

            // Mark all transactions as committed
            PublishAsCommitted(batch);

            return(lastTransactionId);
        }