Skip to content

fix: resolve SQLite transaction bugs, FTS5 sync, and atomic operations#94

Open
murilloimparavel wants to merge 1 commit intotirth8205:mainfrom
murilloimparavel:fix/sqlite-transactions-and-fts
Open

fix: resolve SQLite transaction bugs, FTS5 sync, and atomic operations#94
murilloimparavel wants to merge 1 commit intotirth8205:mainfrom
murilloimparavel:fix/sqlite-transactions-and-fts

Conversation

@murilloimparavel
Copy link
Copy Markdown

Summary

Fixes multiple SQLite transaction management issues that cause cannot start a transaction within a transaction errors and potential data corruption:

  • BEGIN IMMEDIATE conflict (graph.py): Add in_transaction guard before BEGIN IMMEDIATE to prevent errors when implicit transactions are left open by prior DML operations
  • FTS5 content sync (search.py): Recreate FTS5 table with content='nodes' and use INSERT INTO nodes_fts(nodes_fts) VALUES('rebuild') for proper content-sync population (was creating standalone table disconnected from nodes)
  • Atomic batch operations (flows.py, communities.py): Wrap DELETE + INSERT loops in BEGIN IMMEDIATE / try / COMMIT / except ROLLBACK to prevent partial writes on crash
  • Missing rollback on error (tools/build.py): Add store.rollback() in post-processing except blocks to prevent lingering transactions that corrupt the DB on next run
  • Public rollback API (graph.py): Expose GraphStore.rollback() method instead of accessing _conn directly
  • Diagnostic logging: Add logger.warning() before silent rollbacks in transaction guards for debuggability

Reproduction

The cannot start a transaction within a transaction error occurs when:

  1. store_file_nodes_edges() calls BEGIN IMMEDIATE while a prior operation (e.g., set_metadata, upsert_node) left an implicit Python sqlite3 transaction open
  2. Post-processing steps (signatures, FTS, flows, communities) fail partially without rollback, leaving the DB in a dirty state for the next build

Test plan

  • Full rebuild on monorepo with 8,352 nodes, 50,259 edges — zero transaction errors
  • Verified FTS5 content sync works correctly after rebuild
  • Verified flows (1,185) and communities (605) populated correctly
  • Verified rollback logging appears when uncommitted transactions are detected
  • All 29 CLI functional tests passing

🤖 Generated with Claude Code

…perations

Fixes multiple SQLite transaction management issues:

1. **BEGIN IMMEDIATE conflict** (graph.py): Add `in_transaction` guard
   before `BEGIN IMMEDIATE` to prevent "cannot start a transaction within
   a transaction" errors when implicit transactions are left open.

2. **FTS5 content sync** (search.py): Recreate FTS5 table with
   `content='nodes'` and use `INSERT INTO nodes_fts(nodes_fts)
   VALUES('rebuild')` for proper content-sync population.

3. **Atomic batch operations** (flows.py, communities.py): Wrap
   DELETE + INSERT loops in `BEGIN IMMEDIATE` / `try` / `COMMIT` /
   `except ROLLBACK` to prevent partial writes on crash.

4. **Missing rollback on error** (tools/build.py): Add `store.rollback()`
   in post-processing except blocks to prevent lingering transactions.

5. **Public rollback API** (graph.py): Expose `GraphStore.rollback()`
   method instead of accessing `_conn` directly.

6. **Diagnostic logging**: Add `logger.warning()` before silent rollbacks
   in transaction guards for debuggability.

Tested on monorepo with 8,352 nodes, 50,259 edges — zero transaction
errors after fix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant