Chapter 11 · Transactions, Isolation, Locking, Deadlocks, Retries, and Consistency

Bookmarks and Causal Consistency Across Sessions/Cluster Routing

Apply bookmarks only where AtlasMart workflows need causal read-after-write guarantees, and keep their scope separate from isolation and retry semantics.

Advanced135–170 minutesBookmark + causal-chain labNeo4j 2026.07.1 Community · Cypher 25Python driver 6.3.x optionalLast reviewed: September 2026

Learning outcomes

In a single local Community server, a read after a committed write is straightforward. In a cluster, a later read can be routed differently. A bookmark is a causal dependency token: it tells subsequent work not to run until the database state represented by the bookmark has been established.

01

Explain bookmarks as causal dependencies rather than transaction IDs or global serialization tokens.

02

Use same-session causal chaining and explicit bookmark propagation across sessions.

03

Distinguish bolt:// direct-server URIs from neo4j:// routing intent at the application level.

04

Understand BookmarkManager convenience and its possible latency cost.

05

Provide a deterministic Community simulation while clearly separating true cluster routing behavior.

Chapter 11 baseline · reviewed 9 September 2026

The mandatory lab continues Neo4j Community 2026.07.1, database neo4j, explicit CYPHER 25 for version-sensitive examples, container atlasmart-neo4j, authentication enabled, loopback Bolt/HTTP endpoints, no mandatory APOC/GDS plugin, and AtlasMart domain identifiers established in Chapters 01–10. Neo4j 5.26.30 remains the LTS comparison line. Optional application examples use the official Python driver 6.3.x.

Concurrency evidence note

This generation environment does not run Docker/Neo4j, so no deadlock frequency, wait duration, retry count, latency, lock list or cluster routing output is invented. The labs define deterministic invariants and controlled concurrency procedures that you execute on the disposable local instance. Community can use SHOW TRANSACTIONS for its own work; dbms.listActiveLocks() is currently Enterprise-only and is therefore optional evidence, not a mandatory lab dependency.

1. A bookmark represents “at least this causal state”

After a committed transaction, the driver can receive a bookmark. Supplying that bookmark to later work means the later query waits until the represented state is available before executing. It does not mean every transaction in the system is globally serialized, and it does not replace transaction isolation.

Claim Correct? Why
Bookmark guarantees a causally later read can observe the represented committed state Yes The later work waits for that state to be established
Bookmark makes every concurrent transaction globally serializable No It expresses causal dependency, not a universal serial order
Same session usually carries causal ordering automatically Yes Session bookmark handling chains its own work
BookmarkManager across all queries is free No Current driver docs warn that waiting for latest propagated state can add latency

2. Same-session read-after-write

Python · simplest causal chain
with driver.session(database='neo4j') as session:    session.execute_write(        lambda tx: tx.run(            "MERGE (r:Reservation {reservationId:$id}) "            "SET r.labTag='ch11',r.status='CONFIRMED'", id='CH11-R-CAUSAL'        ).consume()    )    row=session.execute_read(        lambda tx: tx.run(            "MATCH (r:Reservation {reservationId:$id}) RETURN r.status AS status",            id='CH11-R-CAUSAL'        ).single()    )    print(row['status'])

3. Explicitly carry causality to a new session

Python · pass bookmarks between sessions
with driver.session(database='neo4j') as writer:    writer.execute_write(lambda tx: tx.run(        "MATCH (s:Stock {stockId:'CH11-ST-001'}) SET s.version=s.version+1"    ).consume())    bookmarks = writer.last_bookmarks()with driver.session(database='neo4j', bookmarks=bookmarks) as reader:    row = reader.execute_read(lambda tx: tx.run(        "MATCH (s:Stock {stockId:'CH11-ST-001'}) RETURN s.version AS version"    ).single())    print(row['version'])

For auto-commit Session.run(), asking for last_bookmarks() may consume the current result so the transaction can complete and return its bookmark.

4. Cluster routing is optional in this chapter, not fabricated

A routed neo4j:// driver can direct reads and writes according to cluster routing information; Community’s mandatory lab cannot reproduce multi-server lag or routing. Therefore the local exercise proves bookmark APIs and causal chaining only. A licensed Enterprise/Aura cluster exercise may additionally write through a routed driver, open a causally chained read session and record the server/routing context plus observed read-after-write behavior.

Python · optional routed driver shape
cluster_driver = GraphDatabase.driver(    'neo4j://cluster-entry:7687',    auth=('neo4j','<secret>'))# Use the same bookmark patterns shown above; do not hard-code production secrets.

5. Deliberately wrong: use bookmarks everywhere “for consistency”

Unnecessary global bookmark chaining can make unrelated work wait for the latest causal state and increase latency. Define which API flows actually require read-your-writes or causal dependency, then propagate bookmarks only across those flows. A reporting query that has no causal dependency on an immediately preceding checkout write should not automatically inherit that dependency.

Check your understanding

  1. What does a bookmark represent?
  2. Is a bookmark a global serializability guarantee?
  3. What is the easiest way to keep closely related work causally chained?
  4. Can Community reproduce cluster routing/secondary lag?
  5. Why not use a global BookmarkManager indiscriminately?
Review the answers

1. A token for a committed database state that later causal work must wait to have established before execution.

2. No.

3. Keep it in the same driver session when practical.

4. No. The mandatory lab demonstrates bookmark API mechanics locally; true routed behavior needs a cluster/Aura environment.

5. It can make unrelated queries wait for propagated state and add latency.

Summary and next step

Bookmarks order dependent work; they do not repair contention or make retries safe. The final lesson puts all transaction mechanisms into one load test whose first success criterion is invariant preservation, not throughput.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.