Skip to content

Cypher Transactions

Josh Adell edited this page Oct 23, 2013 · 1 revision

Cypher transactions over REST are available in Neo4j 2.0. It is possible to begin a transaction and execute one or more Cypher queries and statements inside of that transaction. If all queries and statements are successful (they produce no errors), the entire transaction can be committed atomically. Until the transaction is committed, it is possible to rollback the transaction and undo and data changes made. If any of the Cypher queries are unsuccessful, the transaction is automatically rolled back. More information is available in the Neo4j documentation on REST transactions

Beginning a Transaction

A Cypher transaction is opened on the client using the Client::beginTransaction method

$transaction = $client->beginTransaction();

This method call will not make any requests to the server. No requests are made until the first Cypher statement is added to the transaction.

The return value of Client::beginTransaction is a Transaction object, which is used to manage the transaction and add Cypher queries.

Adding Queries to a Transaction

One or more Cypher queries can be added to a transaction by calling Transaction::addStatements(). While adding queries, it is also possible to signal that the given queries are the last in the transaction and the transaction should be committed.

The return value of Transaction::addStatements() is an array of ResultSets, one per query, in the order the queries were added. If a single query was given, a single result set will be returned.

use Everyman\Neo4j\Cypher\Query;

$transaction = $client->beginTransaction();

// Add a single query to a transaction, $result is a single ResultSet object
$query = new Query($client, 'MATCH n WHERE id(n)={nodeId} RETURN n', array('nodeId' => 123));
$result = $transaction->addStatements($query);

// Add multiple queries, $results is an array of ResultSet objects
$queryA = new Query($client, 'CREATE n RETURN n', array('nodeId' => 123));
$queryB = new Query($client, 'MATCH ()-[r:IN]->() RETURN r');
$results = $transaction->addStatements(array($queryA, $queryB));

// Add a query and commit the transaction
$queryC = new Query($client, 'MATCH n WHERE n.name = {name} RETURN n', array('name' => 'Arthur Dent'));
$result = $transaction->addStatements($queryC, true);

Note: Cypher queries may still be committed outside of a transaction (see Cypher and Gremlin Queries). Unless the are executed using Transaction::addStatements(), they are not executed as part of the transaction. Calling Query::getResultSet() will execute the query outside of the transaction and will not see or be able to interact with any data modified inside the transaction.

Managing a Transaction

A transaction can be committed without adding any statements using Transaction::commit(). Once the transaction is committed, no more statements may be added, and further calls to commit will throw an exception.

$transaction->commit();

If code outside the transaction fails, it may be necessary to cancel the transaction without committing it. Transaction::rollback() will close the transaction and undo any changes done in the context of the transaction.

$transaction->rollback();

Once the transaction has been committed or rolled back it will be closed, and any further attempts to add statements to, commit or rollback transaction will throw an exception. Transaction::isClosed() returns a boolean indicating if a transaction has been committed or rolled back, and Transaction::isError() returns a boolean indicating if the transaction experienced an error:

if ($transaction->isClosed()) {
	echo "No more statements can be added!";
}

if ($transaction->isError()) {
	echo "One or more of my queries failed!";
}

Transactions over REST have a timeout of 60 seconds. If no activity has been made against the transaction before it times out, it will automatically rollback and close. Every time statements are added, the transaction timeout resets to 60 seconds. It may be desirable to reset the transaction timeout without adding any statements. To do this, use the Transaction::keepAlive() method:

$transaction->keepAlive();

As with all the transaction methods, once the transaction is closed, further calls to Transaction::keepAlive() will throw an exception.

Clone this wiki locally