Coordinate transactions and enforce causal consistency

When working with a cluster, bookmarks allow you to chain transactions and enforce causal consistency. A bookmark is a token that represents some state of the database. By passing one or multiple bookmarks along with a query, the server will make sure that the query does not get executed before the represented state(s) have been established.

On requests that commit a transaction (i.e. to the tx/commit and tx/<n>/commit endpoints), the response includes a lastBookmarks key containing an array of encoded bookmarks, which represent the state of the transaction’s committed changes.

Example request

POST http://localhost:7474/db/neo4j/tx/commit
Accept: application/json;charset=UTF-8
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
{
  "statements": [
    {
      "statement": "MERGE (p1:Person {name: $name}) MERGE (p2:Person {name: $otherName}) RETURN p1.name, p2.name",
      "parameters": {
        "name": "Alice",
        "otherName": "Bob"
      }
    }
  ]
}

Example response

200: OK
Content-Type: application/json;charset=utf-8
{
  "results": [ {
    "columns": [ "p1.name", "p2.name" ],
    "data": [ {
      "row": [ "Alice", "Bob" ],
      "meta": [ null, null ]
    } ]
  } ],
  "errors": [],
  "lastBookmarks": [
    "FB:kcwQt8DpQx5zR0uN3Oj/OudM3QaQ"
  ]
}

You can use the bookmarks returned in the response in a subsequent transaction’s Bookmarks header, if you want to causally chain those transactions together. This header should contain a list of bookmark strings. The server waits until it has caught up with the changes encapsulated in the bookmarks before executing the submitted transaction.

In the example below, the server does not execute the transaction until it has registered the changes associated with the bookmarks FB:kcwQt8DpQx5zR0uN3Oj/OudM3QaQ and FB:kcwQy9mp3ioyRom386bZDRRcuCiQ.

Example request

POST http://localhost:7474/db/neo4j/tx/commit
Accept: application/json;charset=UTF-8
Content-Type: application/json
Authorization: Basic bmVvNGo6dmVyeXNlY3JldA==
Bookmarks: ["FB:kcwQt8DpQx5zR0uN3Oj/OudM3QaQ", "FB:kcwQy9mp3ioyRom386bZDRRcuCiQ"]
{
  "statements": [
    {
      "statement": "MATCH (p1:Person {name: $source}) MATCH (p2:Person {name: $end}) MERGE (p1)-[:LIKES]->(p2)",
      "parameters": {
        "source": "Alice",
        "end": "Bob"
      }
    }
  ]
}

Bookmarks returned by the server are not intended to be parsed or modified by the client and should simply be inserted as is into the Bookmarks header.

Glossary

Aura

Aura is Neo4j’s fully managed cloud service. It comes with both free and paid plans.

Cypher

Cypher is Neo4j’s graph query language that lets you retrieve data from the database. It is like SQL, but for graphs.

ACID

Atomicity, Consistency, Isolation, Durability (ACID) are properties guaranteeing that database transactions are processed reliably. An ACID-compliant DBMS ensures that the data in the database remains accurate and consistent despite failures.

causal consistency

A database is causally consistent if read and write queries are seen by every member of the cluster in the same order. This is stronger than eventual consistency.

transaction

A transaction is a unit of work that is either committed in its entirety or rolled back on failure. An example is a bank transfer: it involves multiple steps, but they must all succeed or be reverted, to avoid money being subtracted from one account but not added to the other.