Skip to content

Add Collection#upsertAndReturnOlderDocument for atomic pre-write snap… - #328

Open
bhubam wants to merge 1 commit into
mainfrom
AAP-13921-upsert-return-older
Open

bhubam wants to merge 1 commit into
mainfrom
AAP-13921-upsert-return-older

Conversation

@bhubam

@bhubam bhubam commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

…shots

Callers that need the previous version of a document in order to emit a change event currently have to issue a separate read before the write. That read is not atomic with respect to the write, so a concurrent upsert on the same key can land in between and the "previous" snapshot ends up already holding the new value.

Add a merge-upsert that hands back the pre-write document as part of the write itself. Mongo uses findOneAndUpdate with ReturnDocument.BEFORE; both Postgres collections do the read and the upsert inside a single transaction, with the read taking a row lock. An empty Optional means the document did not exist and this call created it.

Description

Please include a summary of the change, motivation and context.

Testing

Please describe the tests that you ran to verify your changes. Please summarize what did you test and what needs to be tested e.g. deployed and tested helm chart locally.

Checklist:

  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • Any dependent changes have been merged and published in downstream modules

Documentation

Make sure that you have documented corresponding changes in this repository or hypertrace docs repo if required.

…shots

Callers that need the previous version of a document in order to emit a
change event currently have to issue a separate read before the write.
That read is not atomic with respect to the write, so a concurrent upsert
on the same key can land in between and the "previous" snapshot ends up
already holding the new value.

Add a merge-upsert that hands back the pre-write document as part of the
write itself. Mongo uses findOneAndUpdate with ReturnDocument.BEFORE;
both Postgres collections do the read and the upsert inside a single
transaction, with the read taking a row lock. An empty Optional means the
document did not exist and this call created it.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codecov

codecov Bot commented Oct 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 13.92405% with 68 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.54%. Comparing base (cd897e9) to head (70abb05).

Files with missing lines Patch % Lines
...documentstore/postgres/FlatPostgresCollection.java 0.00% 46 Missing ⚠️
...ore/documentstore/postgres/PostgresCollection.java 0.00% 22 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (cd897e9) and HEAD (70abb05). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (cd897e9) HEAD (70abb05)
integration 1 0
Additional details and impacted files
@@              Coverage Diff              @@
##               main     #328       +/-   ##
=============================================
- Coverage     81.23%   58.54%   -22.69%     
- Complexity     1698     1704        +6     
=============================================
  Files           243      243               
  Lines          7780     7859       +79     
  Branches        771      774        +3     
=============================================
- Hits           6320     4601     -1719     
- Misses          962     2773     +1811     
+ Partials        498      485       -13     
Flag Coverage Δ
integration ?
unit 58.54% <13.92%> (-0.30%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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