Run your own transactions
When querying the database with execute_query(), the driver automatically creates a transaction.
A transaction is a unit of work that is either committed in its entirety or rolled back on failure.
You can include multiple Cypher statements in a single query, as for example when using MATCH and CREATE in sequence to update the database, but you cannot have multiple queries and interleave some client-logic in between them.
For these more advanced use-cases, the driver provides functions to manually control transactions.
The most common form is managed transactions, and you can think of them as a way of unwrapping the flow of .execute_query() and being able to specify its desired behavior in more places.
Create a session
Before running a transaction, you need to obtain a session. Sessions act as query channels between the driver and the server, and ensure causal consistency is enforced.
Sessions are created with the method Driver.session(), with the keyword argument database allowing to specify the target database.
For further parameters, see Session configuration.
with driver.session(database="<database-name>") as session:
...
Creating a session is a lightweight operation, so sessions can be created and destroyed without significant cost. Always close sessions when you are done with them.
Sessions are not thread safe: you can share the main Driver object across threads, but each thread should create its own sessions.
Run a managed transaction
A transaction can contain multiple queries. As Neo4j is ACID compliant, queries within a transaction will either be executed as a whole or not at all: you cannot get a part of the transaction succeeding and another failing. Use transactions to group together related queries which work together to achieve a single logical database operation.
You create a managed transaction with the methods Session.execute_read() and Session.execute_write(), depending on whether you want to retrieve data from the database or alter it.
Both methods take a transaction function callback, which is responsible for carrying out the queries and processing the result.
Al.def match_person_nodes(tx, name_filter): (3)
result = tx.run(""" (4)
MATCH (p:Person) WHERE p.name STARTS WITH $filter
RETURN p.name AS name ORDER BY name
""", filter=name_filter)
return list(result) # a list of Record objects (5)
with driver.session(database="<database-name>") as session: (1)
people = session.execute_read( (2)
match_person_nodes,
"Al",
)
for person in people:
print(person.data()) # obtain dict representation