Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Data Neo4j transaction: keep the command inside one managed unit

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

Neo4jClient participates in Spring transactions; an unrelated driver session can escape the command boundary.

Choose one graph mutation

Assigning a driver to a shipment creates or updates a relationship and writes an audit node. If both must commit together, enter through a Spring-managed @Transactional service and use Neo4jClient or repositories bound to that transaction. A raw driver session created outside it is a different unit of work. Thread switches do not carry an imperative transaction.

Keep remote calls outside

Do not call a fleet API midway and tell the caller all effects rolled back if the database later fails. Commit the graph state and an outbox event together, then deliver externally. Outbox boundaries make that obligation explicit.

Prove rollback

Force the audit write to fail after the relationship update and assert neither graph change survives. Repeat through a separately obtained driver session to reveal an escape. The sketch is a service boundary; it needs repository implementations and a Neo4j-backed integration test.

Implementation sketch

Java
@Transactional
public void assignDriver(AssignmentCommand command) {
    shipmentGraph.assign(command.tenantId(), command.shipmentId(),
        command.driverId());
    assignmentAudit.record(command.assignmentId(), command.tenantId());
}

Cost and verification

A transaction holds a connection and locks relevant graph data. Keep the work bounded; a remote call lengthens contention and cannot join the database commit.

Common Mistakes

  • Do not assume a raw driver session joins a Spring transaction automatically.
  • Do not start an async worker inside the transaction and expect it to inherit context.
  • Do not include an external HTTP side effect in the rollback promise.

Read next

Spring Data Neo4j relationships: save only the graph you own, Spring imperative transaction: a worker thread does not inherit it, Spring outbox transaction boundaries: where atomicity ends.

Related boundary

Spring Data Neo4j relationship properties: preserve edge identity

spring
spring-boot
data-transactions
neo4j-transaction-boundary
Storage details