Search in sources :

Example 11 with PhysicalTransactionRepresentation

use of org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation in project neo4j by neo4j.

the class LegacyBatchIndexApplierTest method shouldOrderTransactionsMakingLegacyIndexChanges.

@Test
public void shouldOrderTransactionsMakingLegacyIndexChanges() throws Throwable {
    // GIVEN
    Map<String, Integer> names = MapUtil.genericMap("first", 0, "second", 1);
    Map<String, Integer> keys = MapUtil.genericMap("key", 0);
    String applierName = "test-applier";
    LegacyIndexApplierLookup applierLookup = mock(LegacyIndexApplierLookup.class);
    when(applierLookup.newApplier(anyString(), anyBoolean())).thenReturn(mock(TransactionApplier.class));
    IndexConfigStore config = newIndexConfigStore(names, applierName);
    // WHEN multiple legacy index transactions are running, they should be done in order
    SynchronizedArrayIdOrderingQueue queue = new SynchronizedArrayIdOrderingQueue(10);
    final AtomicLong lastAppliedTxId = new AtomicLong(-1);
    Race race = new Race();
    for (long i = 0; i < 100; i++) {
        final long txId = i;
        race.addContestant(() -> {
            try (LegacyBatchIndexApplier applier = new LegacyBatchIndexApplier(config, applierLookup, queue, INTERNAL)) {
                TransactionToApply txToApply = new TransactionToApply(new PhysicalTransactionRepresentation(new ArrayList<>()));
                FakeCommitment commitment = new FakeCommitment(txId, mock(TransactionIdStore.class));
                commitment.setHasLegacyIndexChanges(true);
                txToApply.commitment(commitment, txId);
                TransactionApplier txApplier = applier.startTx(txToApply);
                // Make sure threads are unordered
                Thread.sleep(ThreadLocalRandom.current().nextInt(5));
                // THEN
                assertTrue(lastAppliedTxId.compareAndSet(txId - 1, txId));
                // Closing manually instead of using try-with-resources since we have no additional work to do in
                // txApplier
                txApplier.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        queue.offer(txId);
    }
    race.go();
}
Also used : TransactionIdStore(org.neo4j.kernel.impl.transaction.log.TransactionIdStore) IndexConfigStore(org.neo4j.kernel.impl.index.IndexConfigStore) ArrayList(java.util.ArrayList) Matchers.anyString(org.mockito.Matchers.anyString) AtomicLong(java.util.concurrent.atomic.AtomicLong) SynchronizedArrayIdOrderingQueue(org.neo4j.kernel.impl.util.SynchronizedArrayIdOrderingQueue) Race(org.neo4j.test.Race) FakeCommitment(org.neo4j.kernel.impl.transaction.log.FakeCommitment) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) Test(org.junit.Test)

Example 12 with PhysicalTransactionRepresentation

use of org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation in project neo4j by neo4j.

the class CoreReplicatedContentMarshalTest method shouldMarshalTransactionReference.

@Test
public void shouldMarshalTransactionReference() throws Exception {
    ByteBuf buffer = Unpooled.buffer();
    PhysicalTransactionRepresentation representation = new PhysicalTransactionRepresentation(Collections.emptyList());
    representation.setHeader(new byte[] { 0 }, 1, 1, 1, 1, 1, 1);
    ReplicatedContent replicatedTx = ReplicatedTransactionFactory.createImmutableReplicatedTransaction(representation);
    assertMarshalingEquality(buffer, replicatedTx);
}
Also used : ByteBuf(io.netty.buffer.ByteBuf) NetworkFlushableByteBuf(org.neo4j.causalclustering.messaging.NetworkFlushableByteBuf) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) Test(org.junit.Test)

Example 13 with PhysicalTransactionRepresentation

use of org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation in project neo4j by neo4j.

the class KernelTransactionImplementation method commit.

private long commit() throws TransactionFailureException {
    boolean success = false;
    long txId = READ_ONLY;
    try (CommitEvent commitEvent = transactionEvent.beginCommitEvent()) {
        // Trigger transaction "before" hooks.
        if (hasDataChanges()) {
            try {
                hooksState = hooks.beforeCommit(txState, this, storageEngine.storeReadLayer(), storageStatement);
                if (hooksState != null && hooksState.failed()) {
                    TransactionHookException cause = hooksState.failure();
                    throw new TransactionFailureException(Status.Transaction.TransactionHookFailed, cause, "");
                }
            } finally {
                beforeHookInvoked = true;
            }
        }
        // Convert changes into commands and commit
        if (hasChanges()) {
            // grab all optimistic locks now, locks can't be deferred any further
            statementLocks.prepareForCommit();
            // use pessimistic locks for the rest of the commit process, locks can't be deferred any further
            Locks.Client commitLocks = statementLocks.pessimistic();
            // Gather up commands from the various sources
            Collection<StorageCommand> extractedCommands = new ArrayList<>();
            storageEngine.createCommands(extractedCommands, txState, storageStatement, commitLocks, lastTransactionIdWhenStarted);
            if (hasLegacyIndexChanges()) {
                legacyIndexTransactionState.extractCommands(extractedCommands);
            }
            /* Here's the deal: we track a quick-to-access hasChanges in transaction state which is true
                 * if there are any changes imposed by this transaction. Some changes made inside a transaction undo
                 * previously made changes in that same transaction, and so at some point a transaction may have
                 * changes and at another point, after more changes seemingly,
                 * the transaction may not have any changes.
                 * However, to track that "undoing" of the changes is a bit tedious, intrusive and hard to maintain
                 * and get right.... So to really make sure the transaction has changes we re-check by looking if we
                 * have produced any commands to add to the logical log.
                 */
            if (!extractedCommands.isEmpty()) {
                // Finish up the whole transaction representation
                PhysicalTransactionRepresentation transactionRepresentation = new PhysicalTransactionRepresentation(extractedCommands);
                TransactionHeaderInformation headerInformation = headerInformationFactory.create();
                long timeCommitted = clock.millis();
                transactionRepresentation.setHeader(headerInformation.getAdditionalHeader(), headerInformation.getMasterId(), headerInformation.getAuthorId(), startTimeMillis, lastTransactionIdWhenStarted, timeCommitted, commitLocks.getLockSessionId());
                // Commit the transaction
                success = true;
                TransactionToApply batch = new TransactionToApply(transactionRepresentation);
                txId = transactionId = commitProcess.commit(batch, commitEvent, INTERNAL);
                commitTime = timeCommitted;
            }
        }
        success = true;
        return txId;
    } catch (ConstraintValidationException | CreateConstraintFailureException e) {
        throw new ConstraintViolationTransactionFailureException(e.getUserMessage(new KeyReadTokenNameLookup(currentTransactionOperations.keyReadOperations())), e);
    } finally {
        if (!success) {
            rollback();
        } else {
            afterCommit(txId);
        }
    }
}
Also used : ConstraintViolationTransactionFailureException(org.neo4j.kernel.api.exceptions.ConstraintViolationTransactionFailureException) KeyReadTokenNameLookup(org.neo4j.kernel.api.KeyReadTokenNameLookup) StorageCommand(org.neo4j.storageengine.api.StorageCommand) ConstraintValidationException(org.neo4j.kernel.api.exceptions.schema.ConstraintValidationException) ArrayList(java.util.ArrayList) Locks(org.neo4j.kernel.impl.locking.Locks) StatementLocks(org.neo4j.kernel.impl.locking.StatementLocks) TransactionHookException(org.neo4j.kernel.api.exceptions.TransactionHookException) TransactionFailureException(org.neo4j.kernel.api.exceptions.TransactionFailureException) ConstraintViolationTransactionFailureException(org.neo4j.kernel.api.exceptions.ConstraintViolationTransactionFailureException) CommitEvent(org.neo4j.kernel.impl.transaction.tracing.CommitEvent) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) CreateConstraintFailureException(org.neo4j.kernel.api.exceptions.schema.CreateConstraintFailureException)

Example 14 with PhysicalTransactionRepresentation

use of org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation in project neo4j by neo4j.

the class ApplyRecoveredTransactionsTest method applyExternalTransaction.

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));
}
Also used : TransactionToApply(org.neo4j.kernel.impl.api.TransactionToApply) LockService(org.neo4j.kernel.impl.locking.LockService) TransactionRepresentation(org.neo4j.kernel.impl.transaction.TransactionRepresentation) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) NeoStoreBatchTransactionApplier(org.neo4j.kernel.impl.transaction.command.NeoStoreBatchTransactionApplier) CacheAccessBackDoor(org.neo4j.kernel.impl.core.CacheAccessBackDoor) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation)

Example 15 with PhysicalTransactionRepresentation

use of org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation in project neo4j by neo4j.

the class TransactionRecordStateTest method movingBilaterallyOfTheDenseNodeThresholdIsConsistent.

@Test
public void movingBilaterallyOfTheDenseNodeThresholdIsConsistent() throws Exception {
    // GIVEN
    NeoStores neoStores = neoStoresRule.open(GraphDatabaseSettings.dense_node_threshold.name(), "10");
    TransactionRecordState tx = newTransactionRecordState(neoStores);
    long nodeId = neoStores.getNodeStore().nextId();
    tx.nodeCreate(nodeId);
    int typeA = (int) neoStores.getRelationshipTypeTokenStore().nextId();
    tx.createRelationshipTypeToken("A", typeA);
    createRelationships(neoStores, tx, nodeId, typeA, INCOMING, 20);
    BatchTransactionApplier applier = new NeoStoreBatchTransactionApplier(neoStores, mock(CacheAccessBackDoor.class), LockService.NO_LOCK_SERVICE);
    apply(applier, transaction(tx));
    tx = newTransactionRecordState(neoStores);
    int typeB = 1;
    tx.createRelationshipTypeToken("B", typeB);
    // WHEN
    // i remove enough relationships to become dense and remove enough to become not dense
    long[] relationshipsOfTypeB = createRelationships(neoStores, tx, nodeId, typeB, OUTGOING, 5);
    for (long relationshipToDelete : relationshipsOfTypeB) {
        tx.relDelete(relationshipToDelete);
    }
    PhysicalTransactionRepresentation ptx = transactionRepresentationOf(tx);
    apply(applier, ptx);
    // THEN
    // The dynamic label record in before should be the same id as in after, and should be in use
    final AtomicBoolean foundRelationshipGroupInUse = new AtomicBoolean();
    ptx.accept(command -> ((Command) command).handle(new CommandVisitor.Adapter() {

        @Override
        public boolean visitRelationshipGroupCommand(Command.RelationshipGroupCommand command) throws IOException {
            if (command.getAfter().inUse()) {
                if (!foundRelationshipGroupInUse.get()) {
                    foundRelationshipGroupInUse.set(true);
                } else {
                    fail();
                }
            }
            return false;
        }
    }));
    assertTrue("Did not create relationship group command", foundRelationshipGroupInUse.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) NeoStores(org.neo4j.kernel.impl.store.NeoStores) NeoStoreBatchTransactionApplier(org.neo4j.kernel.impl.transaction.command.NeoStoreBatchTransactionApplier) RelationshipGroupCommand(org.neo4j.kernel.impl.transaction.command.Command.RelationshipGroupCommand) NeoStoreBatchTransactionApplier(org.neo4j.kernel.impl.transaction.command.NeoStoreBatchTransactionApplier) BatchTransactionApplier(org.neo4j.kernel.impl.api.BatchTransactionApplier) CacheAccessBackDoor(org.neo4j.kernel.impl.core.CacheAccessBackDoor) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) Test(org.junit.Test)

Aggregations

PhysicalTransactionRepresentation (org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation)35 Test (org.junit.Test)15 StorageCommand (org.neo4j.storageengine.api.StorageCommand)9 ArrayList (java.util.ArrayList)7 LogEntryCommand (org.neo4j.kernel.impl.transaction.log.entry.LogEntryCommand)6 TransactionToApply (org.neo4j.kernel.impl.api.TransactionToApply)5 TransactionRepresentation (org.neo4j.kernel.impl.transaction.TransactionRepresentation)5 LogEntry (org.neo4j.kernel.impl.transaction.log.entry.LogEntry)4 LogEntryStart (org.neo4j.kernel.impl.transaction.log.entry.LogEntryStart)4 ByteBuf (io.netty.buffer.ByteBuf)3 NetworkFlushableByteBuf (org.neo4j.causalclustering.messaging.NetworkFlushableByteBuf)3 NeoStores (org.neo4j.kernel.impl.store.NeoStores)3 Command (org.neo4j.kernel.impl.transaction.command.Command)3 LogEntryWriter (org.neo4j.kernel.impl.transaction.log.entry.LogEntryWriter)3 OnePhaseCommit (org.neo4j.kernel.impl.transaction.log.entry.OnePhaseCommit)3 ReplicatedTransaction (org.neo4j.causalclustering.core.state.machines.tx.ReplicatedTransaction)2 TransactionFailureException (org.neo4j.kernel.api.exceptions.TransactionFailureException)2 CacheAccessBackDoor (org.neo4j.kernel.impl.core.CacheAccessBackDoor)2 NodeRecord (org.neo4j.kernel.impl.store.record.NodeRecord)2 NeoStoreBatchTransactionApplier (org.neo4j.kernel.impl.transaction.command.NeoStoreBatchTransactionApplier)2