We maintain counters in a relational database where each incoming request increments or decrements a counter, subject to a maximum limit.
Throughput is 300 requests per second, and many (or all) requests may target the same counter.
For correctness, each request currently performs the following synchronously in a single transaction -
- Read the counter to check whether it can be incremented further.
- Insert a log entry representing the delta.
- Update (increment/decrement) the counter row.
The main issue is high contention: when many transactions update the same counter row, row-level locks cause updates to serialize, leading to increased latency.
Counters - These counters are basically budget (max amount) that a running offer can be used for, if it exceeds beyond that, we would want to stop showing offer to users.
Can using more advanced transactional techniques—such as Serializable Snapshot Isolation (SSI) or other MVCC-based approaches—significantly reduce contention and improve throughput for this kind of highly contended counter update, while still keeping the updates synchronous in the same transaction?