public override void ApplyCommand(ReplicatedTransaction replicatedTx, long commandIndex, System.Action <Result> callback) { lock (this) { if (commandIndex <= _lastCommittedIndex) { _log.debug("Ignoring transaction at log index %d since already committed up to %d", commandIndex, _lastCommittedIndex); return; } TransactionRepresentation tx; sbyte[] extraHeader = encodeLogIndexAsTxHeader(commandIndex); tx = ReplicatedTransactionFactory.ExtractTransactionRepresentation(replicatedTx, extraHeader); int currentTokenId = _lockTokenStateMachine.currentToken().id(); int txLockSessionId = tx.LockSessionId; if (currentTokenId != txLockSessionId && txLockSessionId != Org.Neo4j.Kernel.impl.locking.Locks_Client_Fields.NO_LOCK_SESSION_ID) { callback(Result.of(new TransactionFailureException(LockSessionExpired, "The lock session in the cluster has changed: [current lock session id:%d, tx lock session id:%d]", currentTokenId, txLockSessionId))); } else { try { TransactionToApply transaction = new TransactionToApply(tx, _versionContextSupplier.VersionContext); transaction.OnClose(txId => { if (tx.LatestCommittedTxWhenStarted >= txId) { throw new System.InvalidOperationException(format("Out of order transaction. Expected that %d < %d", tx.LatestCommittedTxWhenStarted, txId)); } callback(Result.of(txId)); _commandIndexTracker.AppliedCommandIndex = commandIndex; }); _queue.queue(transaction); } catch (Exception e) { throw PanicException(e); } } } }
internal ChunkedTransaction(TransactionRepresentation tx) { _txWriter = ReplicatedTransactionFactory.TransactionalRepresentationWriter(tx); }