Database Contention is Real

What is it?

Database contention is a common issue that occurs when multiple users or processes attempt to access the same data or resource at the same time. Contention can lead to a variety of problems, including slow response times, decreased system performance, and even data corruption.

Contending for a resource can happen in any system that relies on a database. For instance, in a banking application, multiple tellers might attempt to update the same customer account at the same time. Similarly, in a web application, multiple users might try to access the same record in a database table simultaneously. In both cases, contention occurs, and the system must resolve the conflict to maintain data integrity.

What problems occur?

Database contention mainly causes data loss due to the many mechanisms databases put in place to avoid contention in the first place. These mechanisms are usually things that block, lock, or slow down writes. Blocking occurs when one process or user holds a lock on a resource, preventing other processes or users from accessing it. Deadlocks occur when two or more processes or users hold locks on resources that the other process requires to proceed, resulting in a standoff. Slowing down occurs when a database uses clocks to try to figure out when to commit a change but can quickly get overrun and lead to a slowdown in overall performance.

Overall, the reality is that your writes will fail to make their way into the database on time and can cause issues for high throughput operations.

A dose of reality

Many developers will fail to identify when contention is occurring specifically because it’s something that occurs at scale, it is captured after the fact, and it is difficult to replicate. The occurrences may not necessarily return errors in your code unless you configure your database to do so (and most default to attempt automatic contention control).

How can you fix it?

It all boils down to database design. You’ll want to identify which data sources are most likely to hit contention and design around them accordingly. The internal strategies that some databases use can easily be replicated to gain more control over their behavior.

Locking Method

The locking method essentially makes sure updates are only written by a subset of allowed operators. The best real-world example of this is a ticketing system like Stub Hub. Once a user places a ticket in their cart, that ticket can only be mutated by the cart holder for a limited time to prevent multiple sales of the same item. The same situation is true when you have multiple entities trying to update the same document. You can resolve it by simply setting a lock on the document and allowing mutations that specifically pass a set of rules that ensure mutations occur without contention.

Batch / Commit Method

The batch and commit method essentially makes sure updates occur linearly with some data-merging strategy behind it. The best real-world example of this is an IoT system like Optra Edge. A single device can produce multiple simultaneous updates for a single entry in the database. To ensure that all updates are committed, updates are written into a separate collection that serves as an update ledger. A separate process later steps in to read the ledger, merge the updates into a single change, then process the update.

Conclusion

Contention occurs in all databases but each one tries to manage it in a different way. None of the "automatic" solutions that databases offer are good enough to account for every use case, most times the best thing to do is to understand the nature of your data and design your database and code to capture all of it without data loss.