Race Condition

If you don't know what is race condition, please read it briefly here:

I'll explain some ways how to handle race condition here:

  • Pessimistic locking

    • Explicitly locks a resource from being accessed simultaneously.

    • Usually done on relational DB by using SELECT ... FOR UPDATE query.

    • Using Redis for distributed lock also falls into this category.

    • More performance overhead than optimistic locking.

    • Might cause deadlock if not careful.

    • More reliable than optimistic locking especially if the write amount is high and the possibility of race condition is high.

  • Optimistic locking

    • Done by checking the data version/timestamp/hash when reading the data and writing the data (version/timestamp/hash must be the same when reading and writing the data).

    • In relational DB, you'll know how many rows are affected by the operation, which will help to detect whether or not the operation on the data is executed.

    • Might be suitable if there are more reads than write.

  • Ordered queue

    • For example, it is possible to use Kafka which ensures ordering within the same partition. This might be more suitable if there's already a message broker in use.

    • Another simple example is to use database as the queue and the tasks can be executed by a worker one by one based on the rows on the database.

Other than that, there might be other way to handle or reduce race conditions. For example, if a website only sells 100 tickets, it might be okay to only allow only 100 people to access the page at the same time. Though, it might still need to apply one of the solutions above.

On a relational DB, you might be able to avoid using lock if what you need is just to increment a column's value. Example query: UPDATE account SET point_amount = point_amount + 5 WHERE id=1;.

Last updated