处理事务与会话
理解如何在应用程序代码中管理事务和会话,实现稳健可靠的数据库交互
处理事务与会话 是 CoddyKit 上的免费 Neo4j Graph Database Fundamentals 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Neo4j Graph Database Fundamentals 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Neo4j Graph Database Fundamentals 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
Why Transactions Matter
When you update data in a database, especially critical information, you want to ensure the operation is reliable. This is where transactions come in.
Transactions help maintain data integrity and consistency, even if something goes wrong during an operation.
Understanding Transactions
A transaction is a single, logical unit of work. It's a sequence of operations performed as a single atomic operation.
Think of it like transferring money between bank accounts: either both the debit and credit happen, or neither does. You wouldn't want money to leave one account without arriving in another!
The ACID Test
Transactions are often described by their ACID properties:
- Atomicity: All or nothing. Either the entire transaction succeeds, or none of it does.
- Consistency: Ensures the database moves from one valid state to another.
- Isolation: Concurrent transactions don't interfere with each other.
- Durability: Once a transaction is committed, its changes are permanent.
Connecting with Sessions
In Neo4j, you interact with the database using sessions. A session manages the communication channel and provides methods to execute Cypher queries.
Sessions are lightweight and designed to be opened and closed frequently. They are your primary interface for running queries, including those within transactions.
Basic Session Read
For simple read operations, you often don't need explicit transaction management. The Neo4j driver handles this for you with a read transaction.
Here's how to fetch a node count using a session:
from neo4j import GraphDatabase
URI = "bolt://localhost:7687"
USERNAME = "neo4j"
PASSWORD = "password"
driver = GraphDatabase.driver(URI, auth=(USERNAME, PASSWORD))
def get_node_count(tx):
result = tx.run("MATCH (n) RETURN count(n) AS count")
return result.single()["count"]
with driver.session() as session:
count = session.read_transaction(get_node_count)
print(f"Total nodes in graph: {count}")
driver.close()Explicit Write Transactions
For operations that modify the database (like CREATE, MERGE, SET, DELETE), it's best practice to use explicit write transactions. This ensures atomicity.
The write_transaction method automatically handles committing if successful, or rolling back if an error occurs.
from neo4j import GraphDatabase
URI = "bolt://localhost:7687"
USERNAME = "neo4j"
PASSWORD = "password"
driver = GraphDatabase.driver(URI, auth=(USERNAME, PASSWORD))
def create_person(tx, name):
tx.run("CREATE (p:Person {name: $name})", name=name)
print(f"Created Person: {name}")
with driver.session() as session:
session.write_transaction(create_person, "Alice")
session.write_transaction(create_person, "Bob")
driver.close()Commit or Rollback?
When using explicit transactions, your changes are not permanently saved until you commit them. If an error occurs, the transaction is rolled back, undoing all changes.
The session.write_transaction() and session.read_transaction() methods handle this implicitly for you. If the function passed to them completes without error, it commits. If an exception is raised, it rolls back.
Robust Error Handling
It's crucial to handle errors within your transaction logic. Any unhandled exception will cause the transaction to roll back, preventing partial updates.
You can use standard Python try...except blocks within your transaction function to manage specific errors or perform cleanup.
from neo4j import GraphDatabase
URI = "bolt://localhost:7687"
USERNAME = "neo4j"
PASSWORD = "password"
driver = GraphDatabase.driver(URI, auth=(USERNAME, PASSWORD))
def create_unique_node(tx, label, name):
try:
# Attempt to create a node. For demo, we'll re-raise to show rollback
tx.run(f"CREATE (n:{label} {{name: $name}})", name=name)
print(f"Node created: {name}")
except Exception as e:
print(f"Error creating node {name}: {e}")
# Re-raise to trigger rollback for the entire write_transaction
raise
with driver.session() as session:
# First call will likely succeed (unless node exists)
try:
session.write_transaction(create_unique_node, "City", "London")
except Exception:
print("Transaction for 'London' rolled back due to error.")
# Second call, intentionally designed to fail for demonstration
# (e.g., if we had a unique constraint on City.name)
try:
# Forcing an error to demonstrate rollback
def force_error(tx):
tx.run("CREATE (x)")
raise ValueError("Simulated error!")
session.write_transaction(force_error)
except Exception:
print("Transaction rolled back due to simulated error.")
driver.close()Pythonic Context Managers
For even finer-grained control, or when performing multiple operations within a single transaction, you can use the session as a context manager and explicitly manage the transaction object.
The session.begin_transaction() method returns a transaction object that also works as a context manager.
from neo4j import GraphDatabase
URI = "bolt://localhost:7687"
USERNAME = "neo4j"
PASSWORD = "password"
driver = GraphDatabase.driver(URI, auth=(USERNAME, PASSWORD))
with driver.session() as session:
with session.begin_transaction() as tx:
tx.run("CREATE (a:Item {id: 1, name: 'Laptop'})")
tx.run("CREATE (b:Item {id: 2, name: 'Mouse'})")
# If no error, transaction commits automatically here when 'with tx' block exits
print("Two items created in one transaction.")
driver.close()Transaction Challenge
Consider a scenario where you are updating two properties of a single node in Neo4j within a Python application. If the second update fails due to a network error, what should happen to the first update if it was part of the same explicit write transaction?
Recap & Next Steps
We've covered the critical role of transactions in maintaining data integrity and consistency in your Neo4j applications.
- Transactions follow ACID properties.
- You use sessions to interact with the database.
session.read_transaction()andsession.write_transaction()provide convenient, atomic operations.- Errors within a transaction lead to an automatic rollback, ensuring no partial data is committed.
- Context managers offer a Pythonic way to manage sessions and transactions.
Understanding transactions is key to building robust and reliable Neo4j applications!
常见问题解答
「处理事务与会话」课时是免费的吗?
是的 — 「处理事务与会话」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Neo4j Graph Database Fundamentals 课程的其余内容,请升级到 CoddyKit PRO。 Neo4j Graph Database Fundamentals 课程共包含 4 节课。
「处理事务与会话」这节课中我会学到什么?
理解如何在应用程序代码中管理事务和会话,实现稳健可靠的数据库交互 你通过在浏览器中直接运行的动手代码来练习 Neo4j Graph Database Fundamentals,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Neo4j Graph Database Fundamentals 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Neo4j Graph Database Fundamentals 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「处理事务与会话」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Neo4j Graph Database Fundamentals 课中编写并运行代码吗?
能。每节 Neo4j Graph Database Fundamentals 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。