#
Async Operations & Locking
Since the graph database handles high-concurrency workloads, many operations are asynchronous to avoid blocking threads.
#
Async Enumeration
If you are processing a large result set, consider using AsEnumerableAsync(). This method parallelizes the reading of data from disk, which can significantly improve performance for heavy queries.
await foreach (var node in Graph.Query().StartAt("Log").AsEnumerableAsync())
{
// Process one by one without buffering everything in memory
await ProcessLogAsync(node);
}
#
Locking and Thread Safety
When modifying the graph, you must use async methods to acquire locks. This ensures thread safety and prevents data corruption.
#
The Locking Pattern
To modify a node, you must follow this specific pattern:
- Acquire Lock: Use
TryGetLockedAsyncorGetOrAddLockedAsyncto get aLockedNode. - Modify: Perform your updates on the
LockedNodeobject. - Commit: Call
CommitAsyncto save changes and release the lock.
warning Important
Locks are exclusive. While you hold a lock on a node, no other thread can read or write to it. Keep your critical sections (the time between lock and commit) as short as possible.
// 1. Acquire Lock
var lockedNode = await Graph.TryGetLockedAsync(someUID);
if (lockedNode != null)
{
try
{
// 2. Modify
// Perform logic that might throw exceptions here
lockedNode.UpdateProperty("visited", true);
// 3. Commit
await Graph.CommitAsync(lockedNode);
}
catch (Exception)
{
// If something goes wrong, abandon changes to release the lock
Graph.AbandonChanges(lockedNode);
throw;
}
}
#
LockedNode vs ReadOnlyNode
- ReadOnlyNode: Lightweight, safe for reading. Returned by queries.
- LockedNode: Heavyweight, represents exclusive access to a node for modification.
#
CommitAsync
The CommitAsync method pushes changes to the storage engine and releases the lock.
// Commit single node
await Graph.CommitAsync(node);
// Commit multiple nodes (atomically)
await Graph.CommitAsync(nodeA, nodeB);
If you modify a node but decide not to save (e.g., validation failed), use AbandonChanges(node).