/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.graphdb;
import java.util.Map;
import org.neo4j.annotations.api.PublicApi;
import org.neo4j.graphdb.schema.Schema;
import org.neo4j.graphdb.traversal.BidirectionalTraversalDescription;
import org.neo4j.graphdb.traversal.TraversalDescription;
/**
* A programmatically handled transaction.
*
* All database operations that access the graph, indexes, or the schema must be performed in a transaction.
*
* If you attempt to access the graph outside of a transaction, those operations will throw
* {@link NotInTransactionException}.
*
* Here's the idiomatic use of programmatic transactions in Neo4j:
*
*
*
* try ( Transaction tx = graphDb.beginTx() )
* {
* // operations on the graph
* // ...
*
* tx.commit();
* }
*
*
*
*
* Let's walk through this example line by line. First we retrieve a Transaction
* object by invoking the {@link GraphDatabaseService#beginTx()} factory method.
* This creates a new transaction which has internal state to keep
* track of whether the current transaction is successful. Then we wrap all
* operations that modify the graph in a try-finally block with the transaction
* as resource. At the end of the block, we invoke the {@link #commit() tx.commit()}
* method to commit that the transaction.
*
* If an exception is raised in the try-block, {@link #commit()} will never be
* invoked and the transaction will be roll backed. This is very important:
* unless {@link #commit()} is invoked, the transaction will fail upon
* {@link #close()}. A transaction can be explicitly rolled back by
* invoking the {@link #rollback()} method.
*
* Read operations inside of a transaction will also read uncommitted data from
* the same transaction.
*
* All {@link ResourceIterable ResourceIterables} that were returned from operations executed inside a transaction
* will be automatically closed when the transaction is committed or rolled back.
* Note however, that the {@link ResourceIterator} should be {@link ResourceIterator#close() closed} as soon as
* possible if you don't intend to exhaust the iterator.
*
*
* Note that transactions should be used by a single thread only.
* It is generally not safe to use a transaction from multiple threads.
* Doing so will lead to undefined behavior.
*/
@PublicApi
public interface Transaction extends AutoCloseable {
/**
* Creates a new node.
*
* @return the created node.
*/
Node createNode();
/**
* Creates a new node and adds the provided labels to it.
*
* @param labels {@link Label labels} to add to the created node.
* @return the created node.
*/
Node createNode(Label... labels);
/**
* Looks up a node by id. Please note: Neo4j reuses its internal ids when
* nodes and relationships are deleted, which means it's bad practice to
* refer to them this way. Instead, use application generated ids.
*
* @param id the id of the node
* @return the node with id id
if found
* @throws NotFoundException if not found
* @deprecated in favor of {@link #getNodeByElementId(String)}.
*/
@Deprecated(since = "5.0", forRemoval = true)
Node getNodeById(long id);
/**
* Looks up a node by element id. Please note: Neo4j reuses its internal ids when
* nodes and relationships are deleted, which means it's bad practice to
* refer to them this way. Instead, use application generated ids.
*
* @param elementId the id of the node
* @return the node with id id
if found
* @throws NotFoundException if not found
*/
Node getNodeByElementId(String elementId);
/**
* Looks up a relationship by id. Please note: Neo4j reuses its internal ids
* when nodes and relationships are deleted, which means it's bad practice
* to refer to them this way. Instead, use application generated ids.
*
* @param id the id of the relationship
* @return the relationship with id id
if found
* @throws NotFoundException if not found
* @deprecated in favor of {@link #getRelationshipByElementId(String)}.
*/
@Deprecated(since = "5.0", forRemoval = true)
Relationship getRelationshipById(long id);
/**
* Looks up a relationship by element id. Please note: Neo4j reuses its internal ids
* when nodes and relationships are deleted, which means it's bad practice
* to refer to them this way. Instead, use application generated ids.
*
* @param elementId the id of the relationship
* @return the relationship with id id
if found
* @throws NotFoundException if not found
*/
Relationship getRelationshipByElementId(String elementId);
/**
* Factory method for bidirectional traversal descriptions.
*
* @return a new {@link BidirectionalTraversalDescription}
*/
BidirectionalTraversalDescription bidirectionalTraversalDescription();
/**
* Factory method for unidirectional traversal descriptions.
*
* @return a new {@link TraversalDescription}
*/
TraversalDescription traversalDescription();
/**
* Executes a query and returns an iterable that contains the result set.
*
* This method is the same as {@link #execute(String, java.util.Map)} with an empty parameters-map.
*
* @param query The query to execute
* @return A {@link org.neo4j.graphdb.Result} that contains the result set.
* @throws QueryExecutionException If the Query contains errors
*/
Result execute(String query) throws QueryExecutionException;
/**
* Executes a query and returns an iterable that contains the result set.
*
* @param query The query to execute
* @param parameters Parameters for the query
* @return A {@link org.neo4j.graphdb.Result} that contains the result set
* @throws QueryExecutionException If the Query contains errors
*/
Result execute(String query, Map parameters) throws QueryExecutionException;
/**
* Returns all labels currently in the underlying store. Labels are added to the store the first time
* they are used. This method guarantees that it will return all labels currently in use.
*
* Please take care that the returned {@link ResourceIterable} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @return all labels in the underlying store.
*/
Iterable getAllLabelsInUse();
/**
* Returns all relationship types currently in the underlying store.
* Relationship types are added to the underlying store the first time they
* are used in a successfully committed {@link Node#createRelationshipTo
* node.createRelationshipTo(...)}. This method guarantees that it will
* return all relationship types currently in use.
*
* @return all relationship types in the underlying store
*/
Iterable getAllRelationshipTypesInUse();
/**
* Returns all labels currently in the underlying store. Labels are added to the store the first time
* they are used. This method guarantees that it will return all labels currently in use. However,
* it may also return more than that (e.g. it can return "historic" labels that are no longer used).
*
* Please take care that the returned {@link ResourceIterable} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @return all labels in the underlying store.
*/
Iterable getAllLabels();
/**
* Returns all relationship types currently in the underlying store.
* Relationship types are added to the underlying store the first time they
* are used in a successfully committed {@link Node#createRelationshipTo
* node.createRelationshipTo(...)}. Note that this method is guaranteed to
* return all known relationship types, but it does not guarantee that it
* won't return more than that (e.g. it can return "historic"
* relationship types that no longer have any relationships in the node
* space).
*
* @return all relationship types in the underlying store
*/
Iterable getAllRelationshipTypes();
/**
* Returns all property keys currently in the underlying store. This method guarantees that it will return all
* property keys currently in use. However, it may also return more than that (e.g. it can return "historic"
* labels that are no longer used).
*
* Please take care that the returned {@link ResourceIterable} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @return all property keys in the underlying store.
*/
Iterable getAllPropertyKeys();
/**
* Returns all nodes having a given label, and a property value of type String or Character matching the
* given value template and search mode.
*
* If an online index is found, it will be used to look up the requested nodes.
* If no indexes exist for the label/property combination, the database will
* scan all labeled nodes looking for matching property values.
*
* The search mode and value template are used to select nodes of interest. The search mode can
* be one of
*
* EXACT: The value has to match the template exactly. This is the same behavior as {@link Transaction#findNode(Label, String, Object)}.
* PREFIX: The value must have a prefix matching the template.
* SUFFIX: The value must have a suffix matching the template.
* CONTAINS: The value must contain the template. Only exact matches are supported.
*
* Note that in Neo4j the Character 'A' will be treated the same way as the String 'A'.
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param label consider nodes with this label
* @param key required property key
* @param template required property value template
* @param searchMode search mode to use for finding matches
* @return an iterator containing all matching nodes. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findNodes(Label label, String key, String template, StringSearchMode searchMode);
/**
* Returns all nodes having the label, and the wanted property values.
* If an online index is found, it will be used to look up the requested
* nodes.
*
* If no indexes exist for the label with all provided properties, the database will
* scan all labeled nodes looking for matching nodes.
*
* Note that equality for values do not follow the rules of Java. This means that the number 42 is equals to all
* other 42 numbers, regardless of whether they are encoded as Integer, Long, Float, Short, Byte or Double.
*
* Same rules follow Character and String - the Character 'A' is equal to the String 'A'.
*
* Finally - arrays also follow these rules. An int[] {1,2,3} is equal to a double[] {1.0, 2.0, 3.0}
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param label consider nodes with this label
* @param propertyValues required property key-value combinations
* @return an iterator containing all matching nodes. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findNodes(Label label, Map propertyValues);
/**
* Returns all nodes having the label, and the wanted property values.
* If an online index is found, it will be used to look up the requested
* nodes.
*
* If no indexes exist for the label with all provided properties, the database will
* scan all labeled nodes looking for matching nodes.
*
* Note that equality for values do not follow the rules of Java. This means that the number 42 is equals to all
* other 42 numbers, regardless of whether they are encoded as Integer, Long, Float, Short, Byte or Double.
*
* Same rules follow Character and String - the Character 'A' is equal to the String 'A'.
*
* Finally - arrays also follow these rules. An int[] {1,2,3} is equal to a double[] {1.0, 2.0, 3.0}
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param label consider nodes with this label
* @param key1 required property key1
* @param value1 required property value of key1
* @param key2 required property key2
* @param value2 required property value of key2
* @param key3 required property key3
* @param value3 required property value of key3
* @return an iterator containing all matching nodes. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findNodes(
Label label, String key1, Object value1, String key2, Object value2, String key3, Object value3);
/**
* Returns all nodes having the label, and the wanted property values.
* If an online index is found, it will be used to look up the requested
* nodes.
*
* If no indexes exist for the label with all provided properties, the database will
* scan all labeled nodes looking for matching nodes.
*
* Note that equality for values do not follow the rules of Java. This means that the number 42 is equals to all
* other 42 numbers, regardless of whether they are encoded as Integer, Long, Float, Short, Byte or Double.
*
* Same rules follow Character and String - the Character 'A' is equal to the String 'A'.
*
* Finally - arrays also follow these rules. An int[] {1,2,3} is equal to a double[] {1.0, 2.0, 3.0}
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param label consider nodes with this label
* @param key1 required property key1
* @param value1 required property value of key1
* @param key2 required property key2
* @param value2 required property value of key2
* @return an iterator containing all matching nodes. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findNodes(Label label, String key1, Object value1, String key2, Object value2);
/**
* Equivalent to {@link #findNodes(Label, String, Object)}, however it must find no more than one
* {@link Node node} or it will throw an exception.
*
* @param label consider nodes with this label
* @param key required property key
* @param value required property value
* @return the matching node or null
if none could be found
* @throws MultipleFoundException if more than one matching {@link Node node} is found
*/
Node findNode(Label label, String key, Object value);
/**
* Returns all nodes having the label, and the wanted property value.
* If an online index is found, it will be used to look up the requested
* nodes.
*
* If no indexes exist for the label/property combination, the database will
* scan all labeled nodes looking for the property value.
*
* Note that equality for values do not follow the rules of Java. This means that the number 42 is equals to all
* other 42 numbers, regardless of whether they are encoded as Integer, Long, Float, Short, Byte or Double.
*
* Same rules follow Character and String - the Character 'A' is equal to the String 'A'.
*
* Finally - arrays also follow these rules. An int[] {1,2,3} is equal to a double[] {1.0, 2.0, 3.0}
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param label consider nodes with this label
* @param key required property key
* @param value required property value
* @return an iterator containing all matching nodes. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findNodes(Label label, String key, Object value);
/**
* Returns all {@link Node nodes} with a specific {@link Label label}.
*
* Please take care that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param label the {@link Label} to return nodes for.
* @return an iterator containing all nodes matching the label. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findNodes(Label label);
/**
* Returns all {@link Relationship relationships} having the {@link RelationshipType type}, and a property value of type String or Character matching the
* given value template and search mode.
*
* If an online index is found, it will be used to look up the requested
* relationships.
* If no indexes exist for the type/property combination, the database will
* scan all relationships of a specific type looking for matching property values.
*
* The search mode and value template are used to select relationships of interest. The search mode can
* be one of
*
* EXACT: The value has to match the template exactly. This is the same behavior
* as {@link Transaction#findRelationships(RelationshipType, String, Object)}.
* PREFIX: The value must have a prefix matching the template.
* SUFFIX: The value must have a suffix matching the template.
* CONTAINS: The value must contain the template. Only exact matches are supported.
*
* Note that in Neo4j the Character 'A' will be treated the same way as the String 'A'.
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param relationshipType consider relationships with this type
* @param key required property key
* @param template required property value template
* @param searchMode search mode to use for finding matches
* @return an iterator containing all matching relationships. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findRelationships(
RelationshipType relationshipType, String key, String template, StringSearchMode searchMode);
/**
* Returns all {@link Relationship relationships} having the {@link RelationshipType type}, and the wanted property values.
* If an online index is found, it will be used to look up the requested
* relationships.
*
* If no indexes exist for the type with all provided properties, the database will
* scan all relationships of a specific type looking for matching values.
*
* Note that equality for values do not follow the rules of Java. This means that the number 42 is equals to all
* other 42 numbers, regardless of whether they are encoded as Integer, Long, Float, Short, Byte or Double.
*
* Same rules follow Character and String - the Character 'A' is equal to the String 'A'.
*
* Finally - arrays also follow these rules. An int[] {1,2,3} is equal to a double[] {1.0, 2.0, 3.0}
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param relationshipType consider relationships with this type
* @param propertyValues required property key-value combinations
* @return an iterator containing all matching relationships. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findRelationships(
RelationshipType relationshipType, Map propertyValues);
/**
* Returns all {@link Relationship relationships} having the {@link RelationshipType type}, and the wanted property values.
* If an online index is found, it will be used to look up the requested
* relationships.
*
* If no indexes exist for the type with all provided properties, the database will
* scan all relationships of a specific type looking for matching values.
*
* Note that equality for values do not follow the rules of Java. This means that the number 42 is equals to all
* other 42 numbers, regardless of whether they are encoded as Integer, Long, Float, Short, Byte or Double.
*
* Same rules follow Character and String - the Character 'A' is equal to the String 'A'.
*
* Finally - arrays also follow these rules. An int[] {1,2,3} is equal to a double[] {1.0, 2.0, 3.0}
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param relationshipType consider relationships with this type
* @param key1 required property key1
* @param value1 required property value of key1
* @param key2 required property key2
* @param value2 required property value of key2
* @param key3 required property key3
* @param value3 required property value of key3
* @return an iterator containing all matching relationships. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findRelationships(
RelationshipType relationshipType,
String key1,
Object value1,
String key2,
Object value2,
String key3,
Object value3);
/**
* Returns all {@link Relationship relationships} having the {@link RelationshipType type}, and the wanted property values.
* If an online index is found, it will be used to look up the requested
* relationships.
*
* If no indexes exist for the type with all provided properties, the database will
* scan all relationships of a specific type looking for matching values.
*
* Note that equality for values do not follow the rules of Java. This means that the number 42 is equals to all
* other 42 numbers, regardless of whether they are encoded as Integer, Long, Float, Short, Byte or Double.
*
* Same rules follow Character and String - the Character 'A' is equal to the String 'A'.
*
* Finally - arrays also follow these rules. An int[] {1,2,3} is equal to a double[] {1.0, 2.0, 3.0}
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param relationshipType consider relationships with this type
* @param key1 required property key1
* @param value1 required property value of key1
* @param key2 required property key2
* @param value2 required property value of key2
* @return an iterator containing all matching relationships. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findRelationships(
RelationshipType relationshipType, String key1, Object value1, String key2, Object value2);
/**
* Equivalent to {@link #findRelationships(RelationshipType, String, Object)}, however it must find no more than one {@link Relationship relationship} or it
* will throw an exception.
*
* @param relationshipType consider relationships with this type
* @param key required property key
* @param value required property value
* @return the matching relationship or null
if none could be found
* @throws MultipleFoundException if more than one matching {@link Relationship relationship} is found
*/
Relationship findRelationship(RelationshipType relationshipType, String key, Object value);
/**
* Returns all {@link Relationship relationships} having the {@link RelationshipType type}, and the wanted property value.
* If an online index is found, it will be used to look up the requested
* relationships.
*
* If no indexes exist for the type/property combination, the database will
* scan all relationships of a specific type looking for the property value.
*
* Note that equality for values do not follow the rules of Java. This means that the number 42 is equals to all
* other 42 numbers, regardless of whether they are encoded as Integer, Long, Float, Short, Byte or Double.
*
* Same rules follow Character and String - the Character 'A' is equal to the String 'A'.
*
* Finally - arrays also follow these rules. An int[] {1,2,3} is equal to a double[] {1.0, 2.0, 3.0}
*
* Please ensure that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param relationshipType consider relationships with this type
* @param key required property key
* @param value required property value
* @return an iterator containing all matching relationships. See {@link ResourceIterator} for responsibilities.
*/
ResourceIterator findRelationships(RelationshipType relationshipType, String key, Object value);
/**
* Returns all {@link Relationship relationships} of a specific {@link RelationshipType type}.
*
* Please take care that the returned {@link ResourceIterator} is closed correctly and as soon as possible
* inside your transaction to avoid potential blocking of write operations.
*
* @param relationshipType the {@link RelationshipType} to return relationships for.
* @return an iterator containing all relationships with matching type. See {@link ResourceIterator} for responsibilities.
* @throws IllegalStateException if relationship index feature not enabled
*/
ResourceIterator findRelationships(RelationshipType relationshipType);
/**
* Marks this transaction as terminated, which means that it will be, much like in the case of failure,
* unconditionally rolled back when {@link #close()} is called. Once this method has been invoked, it doesn't matter
* if {@link #commit()} ()} is invoked afterwards -- the transaction will still be rolled back.
*
* Additionally, terminating a transaction causes all subsequent operations carried out within that
* transaction to throw a {@link TransactionTerminatedException}.
*
* Note that, unlike the other transaction operations, this method can be called from different thread.
* When this method is called, it signals to terminate the transaction and returns immediately.
*
* Calling this method on an already closed transaction has no effect.
*/
void terminate();
/**
* Returns all nodes in the graph.
*
* @return all nodes in the graph.
*/
ResourceIterable getAllNodes();
/**
* Returns all relationships in the graph.
*
* @return all relationships in the graph.
*/
ResourceIterable getAllRelationships();
/**
* Acquires a write lock for {@code entity} for this transaction.
* The lock (returned from this method) can be released manually, but
* if not it's released automatically when the transaction finishes.
*
* @param entity the entity to acquire a lock for. If another transaction
* currently holds a write lock to that entity this call will wait until
* it's released.
*
* @return a {@link Lock} which optionally can be used to release this
* lock earlier than when the transaction finishes. If not released
* (with {@link Lock#release()} it's going to be released when the
* transaction finishes.
*/
Lock acquireWriteLock(Entity entity);
/**
* Acquires a read lock for {@code entity} for this transaction.
* The lock (returned from this method) can be released manually, but
* if not it's released automatically when the transaction finishes.
* @param entity the entity to acquire a lock for. If another transaction
* currently hold a write lock to that entity this call will wait until
* it's released.
*
* @return a {@link Lock} which optionally can be used to release this
* lock earlier than when the transaction finishes. If not released
* (with {@link Lock#release()} it's going to be released with the
* transaction finishes.
*/
Lock acquireReadLock(Entity entity);
/**
* Returns the {@link Schema schema manager} where all things related to schema,
* for example constraints and indexing on {@link Label labels}.
*
* @return the {@link Schema schema manager} for this database.
*/
Schema schema();
/**
* Commit and close current transaction.
*
* When {@code commit()} is completed, all resources are released and no more changes are possible in this transaction.
*/
void commit();
/**
* Roll back and close current transaction.
* When {@code rollback()} is completed, all resources are released and no more changes are possible in this transaction
*/
void rollback();
/**
* Close transaction. If {@link #commit()} or {@link #rollback()} have been called this does nothing.
* If none of them are called, the transaction will be rolled back.
*
*
All {@link ResourceIterable ResourceIterables} that where returned from operations executed inside this
* transaction will be automatically closed by this method in they were not closed before.
*
*
This method comes from {@link AutoCloseable} so that a {@link Transaction} can participate
* in try-with-resource statements.
*/
@Override
void close();
}