v145 · Web APIs · Concurrency Stress
Upsert concurrency stress
Race a pool of "tabs" all hammering the same counter with read-modify-write vs. upsert. Watch the lost-update count climb on one side and stay flat on the other — the whole point of atomic upsert.
scenario
log
code
// Read-modify-write — vulnerable to lost updates if two transactions interleave
async function rmwInc(db, key) {
const tx = db.transaction('counters', 'readwrite');
const s = tx.objectStore('counters');
const cur = await new Promise(r => { const q = s.get(key); q.onsuccess = () => r(q.result || { id: key, n: 0 }); });
cur.n++;
s.put(cur);
return new Promise(r => tx.oncomplete = () => r());
}
// Upsert — single put, conflict-free
async function upsertInc(db, key, n) {
const tx = db.transaction('counters', 'readwrite');
tx.objectStore('counters').put({ id: key, n });
return new Promise(r => tx.oncomplete = () => r());
}