Skip to content

Fix race condition in barrier seq range tracking #1

@rcarver

Description

@rcarver

Problem

There's a race condition between beginBarrier and the user's database write. The current implementation uses seq ranges to identify which undolog entries belong to a barrier:

  1. beginBarrier reads max(seq) as startSeq
  2. ⚠️ Another write could happen here → undolog entries created
  3. User's write happens → undolog entries created
  4. endBarrier reads max(seq) as endSeq, captures range [startSeq+1, endSeq]

If concurrent writes occur between steps 1 and 3, those unrelated undolog entries are incorrectly included in the barrier's range.

Proposed Solution

Tag undolog entries with a barrier ID rather than relying on seq ranges.

Schema change:

-- Add barrierId column to undolog
ALTER TABLE undolog ADD COLUMN barrierId TEXT;

-- Add currentBarrierId to undoState  
ALTER TABLE undoState ADD COLUMN currentBarrierId TEXT;

Trigger change:

INSERT INTO undolog(barrierId, tableName, sql) 
VALUES((SELECT currentBarrierId FROM undoState WHERE id = 1), ...);

API change:

  • beginBarrier sets currentBarrierId in undoState
  • endBarrier queries WHERE barrierId = ? instead of seq range
  • Entries with barrierId = NULL are ignored (written outside a barrier)

Benefits

  • Eliminates race condition entirely
  • Works correctly with concurrent database access
  • No change to public API

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions