Skip to content

feat(dynamodb): optimistic concurrency on update() (#24) - #255

Merged
codeforstartups merged 1 commit into
codeforstartups:developmentfrom
R3108:feat/optimistic-concurrency-24
Sep 25, 2026
Merged

codeforstartups merged 1 commit into
codeforstartups:developmentfrom
R3108:feat/optimistic-concurrency-24

Conversation

@R3108

@R3108 R3108 commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

update() now stores a version attribute on the DynamoDB item and writes it with a ConditionExpression, so a concurrent change raises ConflictError (nothing written) instead of being silently overwritten.

  • DynamoDBStore.put_versioned: conditional put_item that bumps the version; ConditionalCheckFailedException -> ConflictError
  • DynamoDBStore.get_versioned: strongly consistent GetItem incl. version
  • Dynavec.update: optional expected_version=, returns the new version on UpsertResult.version; writes DynamoDB before S3 Vectors so a conflict leaves both stores untouched
  • Plain upsert() stays last-writer-wins and drops the version
  • moto-backed store tests + in-memory client tests for conflicts

Description

Related issue

Fixes #

Changes

Testing

  • Tests pass locally
  • Ruff checks pass
  • Documentation updated, if applicable

Checklist

  • My changes are focused and relevant to this pull request.
  • I have added or updated tests where appropriate.
  • I have reviewed my changes for unrelated modifications.
  • I have updated documentation where necessary.

update() now stores a version attribute on the DynamoDB item and writes
it with a ConditionExpression, so a concurrent change raises
ConflictError (nothing written) instead of being silently overwritten.

- DynamoDBStore.put_versioned: conditional put_item that bumps the
  version; ConditionalCheckFailedException -> ConflictError
- DynamoDBStore.get_versioned: strongly consistent GetItem incl. version
- Dynavec.update: optional expected_version=, returns the new version on
  UpsertResult.version; writes DynamoDB before S3 Vectors so a conflict
  leaves both stores untouched
- Plain upsert() stays last-writer-wins and drops the version
- moto-backed store tests + in-memory client tests for conflicts
@Kaap10

Kaap10 commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Hey @R3108, the code looks great! Could you please clean up the PR description template and add Closes #24 so GitHub links and auto-closes the issue upon merge?

@codeforstartups codeforstartups left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent — real optimistic concurrency for update() (#24). Each item carries a version, and updates write with a ConditionExpression so a concurrent change raises ConflictError (nothing written) instead of a silent lost update. Nice touches: expected_version= to guard across your own read/modify/write cycle, UpsertResult.version returning the new version, and upsert() deliberately staying last-writer-wins. Verified locally: ruff clean, 58 tests pass, CI green. Docs + CHANGELOG updated. Merging — thanks @R3108! 🙌

@codeforstartups
codeforstartups merged commit 437c7bb into codeforstartups:development Sep 25, 2026
3 checks passed
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.

3 participants