Transaction¶
The transaction module provides a unit-of-work pattern for batching graph mutations. Changes are recorded into a Transaction object and then applied atomically by GraphEngine.commit().
Why Transactions?¶
Without transactions, each individual node or edge mutation is immediately persisted. This means:
- A partial failure leaves the data in an inconsistent state.
- There is no natural grouping of related changes for logging or auditing.
With transactions, a set of related changes (e.g. "add a node and connect it to its parent") is either applied in full or not at all (from the in-memory perspective).
Current durability guarantee
The transaction ensures in-memory consistency. Full ACID durability (rollback on DB failure) will be added in a future release. For now, if GraphEngine.commit() raises part-way through, reload the graph from the repository.
The transaction() Context Manager¶
The most ergonomic way to work with transactions is the transaction() context manager:
from knowledge_platform.core.transaction import transaction
with transaction(graph.id) as tx:
tx.record_add_node(parent_node)
tx.record_add_node(child_node)
tx.record_add_edge(edge)
engine.commit(tx)
# tx.committed is True here
If an exception is raised inside the with block before engine.commit() is called, the transaction is marked rolled_back=True and no changes are applied:
with pytest.raises(ValueError):
with transaction(graph.id) as tx:
tx.record_add_node(node)
raise ValueError("something went wrong")
assert tx.rolled_back # True — nothing was applied
assert not tx.committed # False
Manual Usage¶
You can also build a Transaction manually:
from knowledge_platform.core.transaction import Transaction
tx = Transaction(graph_id=graph.id)
tx.record_add_node(node_a)
tx.record_update_node(node_b_updated)
tx.record_remove_edge(old_edge_id)
engine.commit(tx)
Supported Operations¶
record_* method |
Engine operation applied | Payload type |
|---|---|---|
record_add_node(node) |
graph.add_node + repo.save_node |
Node |
record_update_node(node) |
graph.update_node + repo.save_node |
Node |
record_remove_node(node_id) |
graph.remove_node + repo.delete_node |
NodeId |
record_add_edge(edge) |
graph.add_edge + repo.save_edge |
Edge |
record_remove_edge(edge_id) |
graph.remove_edge + repo.delete_edge |
EdgeId |
Guard Conditions¶
Calling any record_* method on a committed or rolled-back transaction raises RuntimeError. Likewise, GraphEngine.commit() refuses a transaction that is already committed or rolled-back.
API Reference¶
knowledge_platform.core.transaction.ChangeRecord
dataclass
¶
Represents a single recorded change within a transaction.
Attributes:
| Name | Type | Description |
|---|---|---|
operation |
str
|
One of |
payload |
Any
|
The entity involved (Node, Edge, or just an ID string). |
Source code in src/knowledge_platform/core/transaction.py
knowledge_platform.core.transaction.Transaction
dataclass
¶
Collects a batch of graph mutations to be committed atomically.
Usage::
tx = Transaction(graph_id=gid)
tx.record_add_node(node)
tx.record_add_edge(edge)
# apply all changes via GraphEngine.commit(tx)
Attributes:
| Name | Type | Description |
|---|---|---|
graph_id |
GraphId
|
The graph this transaction targets. |
changes |
list[ChangeRecord]
|
Ordered list of recorded changes. |
committed |
bool
|
Whether this transaction has been successfully committed. |
rolled_back |
bool
|
Whether this transaction has been rolled back. |
Source code in src/knowledge_platform/core/transaction.py
Functions¶
record_add_edge ¶
Record an edge addition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
edge
|
Edge
|
The edge to add. |
required |
record_add_node ¶
Record a node addition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node
|
Node
|
The node to add. |
required |
record_remove_edge ¶
Record an edge removal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
edge_id
|
EdgeId
|
ID of the edge to remove. |
required |
Source code in src/knowledge_platform/core/transaction.py
record_remove_node ¶
Record a node removal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node_id
|
NodeId
|
ID of the node to remove. |
required |
Source code in src/knowledge_platform/core/transaction.py
knowledge_platform.core.transaction.transaction ¶
Context manager that yields a :class:Transaction for graph_id.
The caller must pass the transaction to
:meth:~knowledge_platform.core.engine.GraphEngine.commit to apply the
changes. If an exception propagates the transaction is marked as
rolled-back (no changes are applied).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph_id
|
GraphId
|
Owning graph identifier. |
required |
Yields:
| Type | Description |
|---|---|
Transaction
|
An open :class: |
Raises:
| Type | Description |
|---|---|
Exception
|
Any exception raised inside the |