Transactions¶
CongraphDB provides ACID transactions to ensure data consistency and integrity.
ACID Guarantees¶
- Atomicity — All operations in a transaction succeed or none do
- Consistency — Database always moves from one valid state to another
- Isolation — Concurrent transactions don't interfere with each other
- Durability — Committed changes persist even after system failure
Basic Transactions¶
Starting a Transaction¶
const conn = db.createConnection();
conn.beginTransaction();
try {
// Your operations here
await conn.query(`CREATE (u:User {name: 'Alice', age: 30})`);
await conn.query(`CREATE (u:User {name: 'Bob', age: 25})`);
// Commit if all succeeds
conn.commit();
} catch (error) {
// Rollback on error
conn.rollback();
throw error;
}
Checking Transaction State¶
Write-Ahead Logging (WAL)¶
CongraphDB uses a write-ahead log for crash recovery:
- All changes are first written to the
.walfile - Changes are applied to the main database file
- WAL is periodically checkpointed and cleared
This ensures that if the process crashes, uncommitted changes can be rolled back and committed changes can be recovered.
Transaction Isolation¶
CongraphDB uses serializable isolation — the strongest isolation level. This means:
- Concurrent transactions appear to execute sequentially
- No dirty reads, non-repeatable reads, or phantom reads
- Guaranteed consistency without manual locking
Performance Considerations¶
Minimize Transaction Duration¶
// Good: Short transaction
conn.beginTransaction();
await conn.query(`CREATE (u:User {name: 'Alice'})`);
conn.commit();
// Avoid: Long-running transactions
conn.beginTransaction();
await slowExternalOperation(); // Don't do this!
await conn.query(`CREATE (u:User {name: 'Alice'})`);
conn.commit();
Batch Operations¶
conn.beginTransaction();
for (let i = 0; i < 1000; i++) {
await conn.query(`CREATE (u:User {name: 'User${i}', age: ${i}})`);
}
conn.commit();
Auto-Checkpoint¶
CongraphDB automatically checkpoints the WAL based on the threshold configured when creating the database:
const db = new Database('./my-graph.cgraph', {
autoCheckpoint: true,
checkpointThreshold: 1000 // Checkpoint after 1000 operations
});
You can also manually trigger a checkpoint:
Complete Example¶
const { Database } = require('congraphdb');
async function transferFriendship(fromUser, toUser, newFriend) {
const db = new Database('./social-graph.cgraph');
db.init();
const conn = db.createConnection();
conn.beginTransaction();
try {
// Verify users exist
const fromResult = await conn.query(`
MATCH (u:User {name: $name}) RETURN u
`, { name: fromUser });
if (fromResult.getNext() === null) {
throw new Error(`User ${fromUser} not found`);
}
const toResult = await conn.query(`
MATCH (u:User {name: $name}) RETURN u
`, { name: toUser });
if (toResult.getNext() === null) {
throw new Error(`User ${toUser} not found`);
}
// Remove old relationship
await conn.query(`
MATCH (u:User {name: $from})-[k:Knows]->(v:User {name: $to})
DELETE k
`, { from: fromUser, to: toUser });
// Create new relationship
await conn.query(`
MATCH (u:User {name: $from})
MATCH (v:User {name: $to})
CREATE (u)-[:Knows {since: $when}]->(v)
`, { from: toUser, to: newFriend, when: Date.now() });
conn.commit();
console.log('Friendship transferred successfully');
} catch (error) {
conn.rollback();
console.error('Transaction failed:', error.message);
throw error;
} finally {
db.close();
}
}
transferFriendship('Alice', 'Bob', 'Charlie').catch(console.error);
Optimistic Concurrency Control (OCC) (v0.1.8+)¶
CongraphDB v0.1.8+ includes Optimistic Concurrency Control for high-concurrency scenarios. See OCC Guide for full details.
OCC-Enabled Transactions¶
For high-concurrency scenarios, use OCC-aware commit:
// Commit with automatic retry on conflict
await conn.commitWithOccSync(10); // max 10 retries
// Execute with retry wrapper
const result = await conn.executeWithRetrySync(5, () => {
return conn.query('MATCH (u:User) RETURN u');
});
OCC Statistics¶
Monitor your application's concurrency patterns:
const stats = await conn.getOccStatistics();
console.log(stats);
// {
// successful_transactions: 1250,
// failed_transactions: 5,
// conflicts_detected: 23,
// total_retries: 18,
// max_retry_count: 3,
// conflict_rate: 1.84 // percentage
// }
Next Steps¶
- Optimistic Concurrency Control — High-concurrency transactions
- Vector Search — Semantic search with embeddings
- Performance — Optimization tips