Skip to content

Optimistic concurrency: auto-increment version field support #20

@mrdevrobot

Description

@mrdevrobot

Summary

BLite currently has no built-in mechanism for optimistic concurrency control. To support EF Core's concurrency tokens and general multi-client scenarios, BLite needs either:

  1. Auto-increment version field: A _version (or configurable name) field that the engine automatically increments on every update, enabling conditional writes ("update only if version == N").
  2. Default version field convention: Documents could carry a _version field by default, but this would require a more invasive refactoring of the storage engine.

Motivation

  • EF Core provider (see Feature: Entity Framework Core provider (BLite.EntityFrameworkCore) BLite.Server#9): EF Core relies on concurrency tokens (e.g., _etag in Cosmos, xmin in PostgreSQL) to implement optimistic concurrency. Without engine-level support, the BLite EF Core provider cannot offer ConcurrencyCheck / [Timestamp] attributes.
  • Multi-client scenarios: When multiple clients update the same document concurrently, stale writes can silently overwrite newer data. A version check on update prevents lost updates.
  • Industry standard: MongoDB has __v, Cosmos DB has _etag, CouchDB has _rev — document databases typically provide some form of optimistic concurrency primitive.

Proposed API

// Option A: Explicit conditional update
await collection.UpdateAsync(id, doc, expectedVersion: 3, ct);
// Throws ConcurrencyException if current version != 3

// Option B: Auto-versioned documents
// Engine automatically manages a _version field
// UpdateAsync checks and increments atomically

Scope

  • Engine-level support in BLite.Core
  • Exposed through BLite client SDK
  • Exposed through gRPC DocumentService and DynamicService
  • REST API support via conditional headers or request body field

Open Questions

  • Should the version field name be configurable or fixed (_version)?
  • Should this be opt-in per collection or enabled globally?
  • How does this interact with transactions (version check inside vs. outside transaction)?
  • Should the version be an integer counter or a hash/timestamp?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions