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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions