Search in sources :

Example 1 with ConstraintValidationException

use of org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.

the class KernelTransactionImplementation method commitTransaction.

private long commitTransaction() throws KernelException {
    boolean success = false;
    long txId = READ_ONLY_ID;
    TransactionListenersState listenersState = null;
    try (CommitEvent commitEvent = transactionEvent.beginCommitEvent()) {
        listenersState = eventListeners.beforeCommit(txState, this, storageReader);
        if (listenersState != null && listenersState.isFailed()) {
            Throwable cause = listenersState.failure();
            if (cause instanceof TransientFailureException) {
                throw (TransientFailureException) cause;
            }
            if (cause instanceof Status.HasStatus) {
                throw new TransactionFailureException(((Status.HasStatus) cause).status(), cause, cause.getMessage());
            }
            throw new TransactionFailureException(Status.Transaction.TransactionHookFailed, cause, cause.getMessage());
        }
        // Convert changes into commands and commit
        if (hasChanges()) {
            forceThawLocks();
            lockClient.prepareForCommit();
            // Gather up commands from the various sources
            HeapTrackingArrayList<StorageCommand> extractedCommands = HeapTrackingCollections.newArrayList(memoryTracker);
            storageEngine.createCommands(extractedCommands, txState, storageReader, commandCreationContext, lockClient, lockTracer(), lastTransactionIdWhenStarted, this::enforceConstraints, cursorContext, memoryTracker);
            /* 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);
                long timeCommitted = clocks.systemClock().millis();
                transactionRepresentation.setHeader(EMPTY_BYTE_ARRAY, startTimeMillis, lastTransactionIdWhenStarted, timeCommitted, leaseClient.leaseId(), securityContext.subject());
                // Commit the transaction
                success = true;
                TransactionToApply batch = new TransactionToApply(transactionRepresentation, cursorContext);
                kernelTransactionMonitor.beforeApply();
                txId = commitProcess.commit(batch, commitEvent, INTERNAL);
                commitTime = timeCommitted;
            }
        }
        success = true;
        return txId;
    } catch (ConstraintValidationException | CreateConstraintFailureException e) {
        throw new ConstraintViolationTransactionFailureException(e.getUserMessage(tokenRead()), e);
    } finally {
        if (!success) {
            rollback(listenersState);
        } else {
            transactionId = txId;
            afterCommit(listenersState);
        }
        transactionMonitor.addHeapTransactionSize(memoryTracker.heapHighWaterMark());
        transactionMonitor.addNativeTransactionSize(memoryTracker.usedNativeMemory());
    }
}
Also used : Status(org.neo4j.kernel.api.exceptions.Status) ConstraintViolationTransactionFailureException(org.neo4j.internal.kernel.api.exceptions.ConstraintViolationTransactionFailureException) TransientFailureException(org.neo4j.graphdb.TransientFailureException) StorageCommand(org.neo4j.storageengine.api.StorageCommand) ConstraintValidationException(org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException) TransactionFailureException(org.neo4j.internal.kernel.api.exceptions.TransactionFailureException) ConstraintViolationTransactionFailureException(org.neo4j.internal.kernel.api.exceptions.ConstraintViolationTransactionFailureException) CommitEvent(org.neo4j.kernel.impl.transaction.tracing.CommitEvent) TransactionListenersState(org.neo4j.kernel.internal.event.TransactionListenersState) PhysicalTransactionRepresentation(org.neo4j.kernel.impl.transaction.log.PhysicalTransactionRepresentation) CreateConstraintFailureException(org.neo4j.internal.kernel.api.exceptions.schema.CreateConstraintFailureException)

Example 2 with ConstraintValidationException

use of org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.

the class ConstraintTestBase method shouldCheckUniquenessWhenAddingLabel.

@Test
void shouldCheckUniquenessWhenAddingLabel() throws Exception {
    // GIVEN
    long nodeConflicting, nodeNotConflicting;
    addConstraints("FOO", "prop");
    try (org.neo4j.graphdb.Transaction tx = graphDb.beginTx()) {
        Node conflict = tx.createNode();
        conflict.setProperty("prop", 1337);
        nodeConflicting = conflict.getId();
        Node ok = tx.createNode();
        ok.setProperty("prop", 42);
        nodeNotConflicting = ok.getId();
        // Existing node
        Node existing = tx.createNode();
        existing.addLabel(Label.label("FOO"));
        existing.setProperty("prop", 1337);
        tx.commit();
    }
    int label;
    try (KernelTransaction tx = beginTransaction()) {
        label = tx.tokenWrite().labelGetOrCreateForName("FOO");
        // This is ok, since it will satisfy constraint
        assertTrue(tx.dataWrite().nodeAddLabel(nodeNotConflicting, label));
        try {
            tx.dataWrite().nodeAddLabel(nodeConflicting, label);
            fail();
        } catch (ConstraintValidationException e) {
        // ignore
        }
        tx.commit();
    }
    // Verify
    try (KernelTransaction tx = beginTransaction();
        NodeCursor nodeCursor = tx.cursors().allocateNodeCursor(tx.cursorContext())) {
        // Node without conflict
        tx.dataRead().singleNode(nodeNotConflicting, nodeCursor);
        assertTrue(nodeCursor.next());
        assertTrue(nodeCursor.labels().contains(label));
        // Node with conflict
        tx.dataRead().singleNode(nodeConflicting, nodeCursor);
        assertTrue(nodeCursor.next());
        assertFalse(nodeCursor.labels().contains(label));
    }
}
Also used : KernelTransaction(org.neo4j.kernel.api.KernelTransaction) Node(org.neo4j.graphdb.Node) ConstraintValidationException(org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException) NodeCursor(org.neo4j.internal.kernel.api.NodeCursor) Test(org.junit.jupiter.api.Test)

Example 3 with ConstraintValidationException

use of org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.

the class ConstraintTestBase method shouldCheckUniquenessWhenAddingProperties.

@Test
void shouldCheckUniquenessWhenAddingProperties() throws Exception {
    // GIVEN
    long nodeConflicting, nodeNotConflicting;
    addConstraints("FOO", "prop");
    try (org.neo4j.graphdb.Transaction tx = graphDb.beginTx()) {
        Node conflict = tx.createNode();
        conflict.addLabel(Label.label("FOO"));
        nodeConflicting = conflict.getId();
        Node ok = tx.createNode();
        ok.addLabel(Label.label("BAR"));
        nodeNotConflicting = ok.getId();
        // Existing node
        Node existing = tx.createNode();
        existing.addLabel(Label.label("FOO"));
        existing.setProperty("prop", 1337);
        tx.commit();
    }
    int property;
    try (KernelTransaction tx = beginTransaction()) {
        property = tx.tokenWrite().propertyKeyGetOrCreateForName("prop");
        // This is ok, since it will satisfy constraint
        tx.dataWrite().nodeSetProperty(nodeNotConflicting, property, intValue(1337));
        try {
            tx.dataWrite().nodeSetProperty(nodeConflicting, property, intValue(1337));
            fail();
        } catch (ConstraintValidationException e) {
        // ignore
        }
        tx.commit();
    }
    // Verify
    try (KernelTransaction tx = beginTransaction();
        NodeCursor nodeCursor = tx.cursors().allocateNodeCursor(tx.cursorContext());
        PropertyCursor propertyCursor = tx.cursors().allocatePropertyCursor(tx.cursorContext(), tx.memoryTracker())) {
        // Node without conflict
        tx.dataRead().singleNode(nodeNotConflicting, nodeCursor);
        assertTrue(nodeCursor.next());
        nodeCursor.properties(propertyCursor);
        assertTrue(hasKey(propertyCursor, property));
        // Node with conflict
        tx.dataRead().singleNode(nodeConflicting, nodeCursor);
        assertTrue(nodeCursor.next());
        nodeCursor.properties(propertyCursor);
        assertFalse(hasKey(propertyCursor, property));
    }
}
Also used : KernelTransaction(org.neo4j.kernel.api.KernelTransaction) Node(org.neo4j.graphdb.Node) ConstraintValidationException(org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException) NodeCursor(org.neo4j.internal.kernel.api.NodeCursor) PropertyCursor(org.neo4j.internal.kernel.api.PropertyCursor) Test(org.junit.jupiter.api.Test)

Example 4 with ConstraintValidationException

use of org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.

the class TransactionImpl method createNode.

@Override
public Node createNode(Label... labels) {
    var ktx = kernelTransaction();
    try {
        TokenWrite tokenWrite = ktx.tokenWrite();
        int[] labelIds = new int[labels.length];
        String[] labelNames = new String[labels.length];
        for (int i = 0; i < labelNames.length; i++) {
            labelNames[i] = labels[i].name();
        }
        tokenWrite.labelGetOrCreateForNames(labelNames, labelIds);
        Write write = ktx.dataWrite();
        long nodeId = write.nodeCreateWithLabels(labelIds);
        return newNodeEntity(nodeId);
    } catch (ConstraintValidationException e) {
        throw new ConstraintViolationException("Unable to add label.", e);
    } catch (SchemaKernelException e) {
        throw new IllegalArgumentException(e);
    } catch (KernelException e) {
        throw new ConstraintViolationException(e.getMessage(), e);
    }
}
Also used : TokenWrite(org.neo4j.internal.kernel.api.TokenWrite) Write(org.neo4j.internal.kernel.api.Write) ConstraintValidationException(org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException) TokenWrite(org.neo4j.internal.kernel.api.TokenWrite) SchemaKernelException(org.neo4j.internal.kernel.api.exceptions.schema.SchemaKernelException) ConstraintViolationException(org.neo4j.graphdb.ConstraintViolationException) InvalidTransactionTypeKernelException(org.neo4j.internal.kernel.api.exceptions.InvalidTransactionTypeKernelException) IndexNotFoundKernelException(org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException) QueryExecutionKernelException(org.neo4j.kernel.impl.query.QueryExecutionKernelException) SchemaKernelException(org.neo4j.internal.kernel.api.exceptions.schema.SchemaKernelException) KernelException(org.neo4j.exceptions.KernelException)

Example 5 with ConstraintValidationException

use of org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException in project neo4j by neo4j.

the class NodeEntity method addLabel.

@Override
public void addLabel(Label label) {
    KernelTransaction transaction = internalTransaction.kernelTransaction();
    int labelId;
    try {
        labelId = transaction.tokenWrite().labelGetOrCreateForName(label.name());
    } catch (IllegalTokenNameException e) {
        throw new ConstraintViolationException(format("Invalid label name '%s'.", label.name()), e);
    } catch (TokenCapacityExceededKernelException e) {
        throw new ConstraintViolationException(e.getMessage(), e);
    } catch (KernelException e) {
        throw new TransactionFailureException("Unknown error trying to create label token", e);
    }
    try {
        transaction.dataWrite().nodeAddLabel(getId(), labelId);
    } catch (ConstraintValidationException e) {
        throw new ConstraintViolationException(e.getUserMessage(transaction.tokenRead()), e);
    } catch (EntityNotFoundException e) {
        throw new NotFoundException("No node with id " + getId() + " found.", e);
    } catch (KernelException e) {
        throw new ConstraintViolationException(e.getMessage(), e);
    }
}
Also used : KernelTransaction(org.neo4j.kernel.api.KernelTransaction) TransactionFailureException(org.neo4j.graphdb.TransactionFailureException) ConstraintValidationException(org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException) ConstraintViolationException(org.neo4j.graphdb.ConstraintViolationException) NotFoundException(org.neo4j.graphdb.NotFoundException) EntityNotFoundException(org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException) TokenCapacityExceededKernelException(org.neo4j.internal.kernel.api.exceptions.schema.TokenCapacityExceededKernelException) EntityNotFoundException(org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException) IllegalTokenNameException(org.neo4j.internal.kernel.api.exceptions.schema.IllegalTokenNameException) PropertyKeyIdNotFoundKernelException(org.neo4j.internal.kernel.api.exceptions.PropertyKeyIdNotFoundKernelException) InvalidTransactionTypeKernelException(org.neo4j.internal.kernel.api.exceptions.InvalidTransactionTypeKernelException) TokenCapacityExceededKernelException(org.neo4j.internal.kernel.api.exceptions.schema.TokenCapacityExceededKernelException) LabelNotFoundKernelException(org.neo4j.internal.kernel.api.exceptions.LabelNotFoundKernelException) KernelException(org.neo4j.exceptions.KernelException)

Aggregations

ConstraintValidationException (org.neo4j.internal.kernel.api.exceptions.schema.ConstraintValidationException)6 KernelTransaction (org.neo4j.kernel.api.KernelTransaction)4 KernelException (org.neo4j.exceptions.KernelException)3 ConstraintViolationException (org.neo4j.graphdb.ConstraintViolationException)3 InvalidTransactionTypeKernelException (org.neo4j.internal.kernel.api.exceptions.InvalidTransactionTypeKernelException)3 Test (org.junit.jupiter.api.Test)2 Node (org.neo4j.graphdb.Node)2 NotFoundException (org.neo4j.graphdb.NotFoundException)2 TransactionFailureException (org.neo4j.graphdb.TransactionFailureException)2 NodeCursor (org.neo4j.internal.kernel.api.NodeCursor)2 EntityNotFoundException (org.neo4j.internal.kernel.api.exceptions.EntityNotFoundException)2 LabelNotFoundKernelException (org.neo4j.internal.kernel.api.exceptions.LabelNotFoundKernelException)2 PropertyKeyIdNotFoundKernelException (org.neo4j.internal.kernel.api.exceptions.PropertyKeyIdNotFoundKernelException)2 IllegalTokenNameException (org.neo4j.internal.kernel.api.exceptions.schema.IllegalTokenNameException)2 TokenCapacityExceededKernelException (org.neo4j.internal.kernel.api.exceptions.schema.TokenCapacityExceededKernelException)2 TransientFailureException (org.neo4j.graphdb.TransientFailureException)1 PropertyCursor (org.neo4j.internal.kernel.api.PropertyCursor)1 TokenWrite (org.neo4j.internal.kernel.api.TokenWrite)1 Write (org.neo4j.internal.kernel.api.Write)1 ConstraintViolationTransactionFailureException (org.neo4j.internal.kernel.api.exceptions.ConstraintViolationTransactionFailureException)1