claude-flow-novice
Version:
Claude Flow Novice - Advanced orchestration platform for multi-agent AI workflows with CFN Loop architecture Includes CodeSearch (hybrid SQLite + pgvector), mem0/memgraph specialists, and all CFN skills.
241 lines (186 loc) • 6.53 kB
Markdown
# Transaction Management in AST-Aware CodeSearch Accelerator
## Overview
This document describes the transaction management improvements implemented to ensure data integrity during multi-step database operations.
## Problem Statement
The original code lacked proper transaction management for:
- Batch entity insertions
- File indexing operations
- Schema migrations
- Multi-table updates
This could lead to:
- Partial updates and data corruption
- Inconsistent database state
- Difficulty recovering from errors
## Solution Architecture
### 1. Transaction-Aware Storage Layer (`store_v2_tx.rs`)
Created a new transaction-aware storage layer that provides:
- Batch operations with automatic transaction wrapping
- Atomic file indexing
- Schema migration support with rollback
- Proper error handling with context
#### Key Features:
```rust
// Batch insert with automatic transaction
let ids = store.insert_entities_batch(&entities)?;
// Atomic file indexing - all or nothing
store.index_file_atomic(file_path, file_hash, |tx| {
// All operations within this closure are atomic
// If an error occurs, everything rolls back
insert_entities(tx)?;
insert_references(tx)?;
insert_embeddings(tx)?;
Ok(())
})?;
// Atomic schema migration
store.migrate_schema_atomic("migration_name", |tx| {
// Migration logic
Ok(())
})?;
```
### 2. Enhanced File Indexing (`index_ast.rs`)
Modified the AST indexing process to use transactions:
- All entities, references, and embeddings for a file are inserted atomically
- Previous data for a file is cleared before inserting new data
- File hash tracking ensures incremental indexing works correctly
```rust
// Original approach - vulnerable to partial updates
for entity in entities {
store.insert_entity(entity)?; // Each call is separate
}
// New approach - atomic
store.index_file_atomic(&file_path, &file_hash, |tx| {
// All operations in a single transaction
for entity in entities {
insert_entity_in_tx(tx, entity)?;
}
Ok(())
})?;
```
### 3. Robust Migration System (`migration_tx.rs`)
Implemented a new migration system with:
- Savepoint-based transactions for nested operations
- Batch processing to avoid long-running transactions
- Progress tracking and error reporting
- Automatic rollback on failures
- Migration validation
```rust
// Atomic migration with validation
MigrationWithTx::migrate_v1_to_v2_atomic(&conn)?;
MigrationWithTx::validate_migration(&conn)?;
```
## Implementation Details
### Transaction Patterns
1. **Simple Transaction**
```rust
let tx = conn.transaction()?;
// ... operations ...
tx.commit()?;
```
2. **Savepoint for Nested Operations**
```rust
let sp = conn.savepoint()?;
// ... operations ...
sp.commit()?; // or sp.rollback()?
```
3. **Atomic Operation Pattern**
```rust
fn atomic_operation<F>(&self, f: F) -> Result<()>
where F: FnOnce(&Transaction) -> Result<()>
{
let tx = self.transaction()?;
f(&tx)?; // May fail
tx.commit()?; // Only commits if f succeeds
Ok(())
}
```
### Error Handling Strategy
1. **Context Preservation**
- All errors include context about what operation failed
- Uses `anyhow::Context` for chainable error messages
2. **Automatic Rollback**
- Dropping a transaction without commit triggers rollback
- Savepoints can be explicitly rolled back
3. **Batch Processing**
- Large operations are split into batches
- Each batch is a separate transaction
- Partial progress is preserved
### Performance Considerations
1. **Statement Preparation**
- Prepared statements are reused within transactions
- Reduces parsing overhead
2. **Batch Size**
- Configurable batch sizes prevent long-running transactions
- Default batch size: 1000 for migrations, 100 for file indexing
3. **Connection Pooling**
- WAL mode enables concurrent readers
- Memory-mapped I/O for better performance
## Usage Examples
### Indexing a File with Transactions
```rust
let store = StoreV2WithTx::new(&db_path)?;
// All operations for the file are atomic
let result = store.index_file_atomic("src/main.rs", "hash123", |tx| {
// Clear existing data for this file
tx.execute("DELETE FROM entities WHERE file_path = ?", ["src/main.rs"])?;
// Insert new entities
for entity in entities {
insert_entity(tx, entity)?;
}
// Insert references
for reference in references {
insert_reference(tx, reference)?;
}
// Update file hash
tx.execute(
"INSERT OR REPLACE INTO file_hashes (file_path, file_hash) VALUES (?, ?)",
["src/main.rs", "hash123"]
)?;
Ok(())
})?;
// If any operation failed, everything rolls back
```
### Migration with Validation
```rust
// Migrate with automatic rollback on errors
match MigrationWithTx::migrate_v1_to_v2_atomic(&conn) {
Ok(()) => {
// Validate migration was successful
MigrationWithTx::validate_migration(&conn)?;
println!("Migration completed successfully");
}
Err(e) => {
eprintln!("Migration failed: {}", e);
// Database remains in original state
}
}
```
## Testing
Comprehensive tests verify:
- Atomic operations rollback on errors
- Transaction isolation works correctly
- Batch operations maintain consistency
- Migration rollback preserves original data
- Concurrent access patterns
Run tests with:
```bash
cargo test transaction
```
## Best Practices
1. **Always use transactions for multi-step operations**
2. **Keep transactions as short as possible**
3. **Use savepoints for nested operations**
4. **Provide meaningful error context**
5. **Validate after complex operations**
## Migration Checklist
When updating existing code to use transactions:
1. Identify multi-step operations
2. Wrap them in transactions or atomic operations
3. Test rollback behavior
4. Add error context
5. Consider batch processing for large operations
## Future Improvements
1. **Distributed Transactions**: Support for multiple database files
2. **Transaction Logging**: Detailed logging of transaction boundaries
3. **Performance Monitoring**: Track transaction durations
4. **Deadlock Detection**: Automatic detection and resolution
5. **Async Support**: Async transaction operations for better concurrency