Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Parallel OCC validation lets a non-transactional write land between validation and Write() (lost update)

Open
#899 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
cpp, node.js
Domain
databases

Research direction

Start with RocksDB's utilities/transactions/optimistic_transaction.cc, especially OptimisticTransaction::CommitWithParallelValidate, and trace how the binding handles non-transactional synchronous writes. The issue lists several possible fix directions but no chosen approach, and notes that a deterministic reproduction needs a sync-point or delay seam between validation and Write(). Done means preventing the lost-update window or establishing and documenting a scoped resolution.

Written by the indexing model from the issue text.

Description

What

Under the default OccValidationPolicy::kValidateParallel, a non-transactional write (putSync/removeSync outside a transaction, which goes to DB::Put or DB::Delete directly) can land between a concurrent optimistic transaction's conflict check and its Write(). The transaction then commits on top of it without ERR_BUSY.

If the transaction read the key (read-modify-write), that is a lost update: the non-transactional value is silently replaced by one computed from the stale read.

Why

OptimisticTransaction::CommitWithParallelValidate (RocksDB utilities/transactions/optimistic_transaction.cc) runs in this order:

  1. Locks the commit's lock buckets.
  2. Runs CheckKeysForConflicts(..., cache_only=true).
  3. Calls db_impl->Write(...).

Non-transactional writes take no buckets, so nothing orders them against the window between steps 2 and 3. A write that lands before step 2 is detected through its sequence number; one that lands between 2 and 3 is not.

With kValidateSerial, validation runs as the write-group callback inside the write thread, so a non-transactional write either precedes the validation (and is detected) or follows the commit. #897 adds RocksDatabase.config({ occValidation: 'serial' }), and its README documents this window.

Status

This is by construction from the RocksDB source. There is no deterministic reproduction yet; one would need a sync-point or delay seam between validation and Write(). Present on main for as long as optimistic transactions have used parallel validation.

Whether Harper is exposed depends on whether any non-transactional synchronous write targets a key that transactions also read-modify-write. That audit is part of the Harper companion change to #897.

Fix directions

  1. Document the window (done in #897), and recommend occValidation: 'serial' where non-transactional and transactional writes mix on the same keys.
  2. Route non-transactional writes on optimistic databases through the same bucket locks: hash the key with the same seed and lock that bucket around DB::Put. RocksDB does not expose the per-database seed or the private pool, so this probably needs a wrapper single-key transaction instead, which costs extra per write.
  3. Wrap the binding's non-transactional writes in a single-operation optimistic transaction. This is simplest, at the price of one transaction per write.

Filed by Claude Opus 5.5 while reworking #897.

Dominant language
C++
Stars
24
Forks
3
Avg merge
1d 7h
Merged PRs (30d)
49

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from HarperFast/rocksdb-js

All issues in HarperFast/rocksdb-js

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.