2 minute read

Concurrency control in RDB

Optimistic lock vs Pessimistic lock

There are two types of locks that exist to solve concurrency problems in RDB.

The first one is pessimistic locking. It uses a lock provided by the RDB. If a clause such as ‘SELECT FOR UPDATE’ is used, the RDB puts an exclusive lock on selected rows so that other queries cannot access them.

Since it uses the lock provided by the database, there are possibilities of encountering deadlock situations.

On the other hand, optimistic locking is done at the application level rather than the database level. It uses the version of the row and employs it in the update clause.

UPDATE optimistic
SET name = newName AND version = 2
WHERE id = 1 AND version = 1

If two clients update at the same time, one client would encounter an error since it could not find the version in the WHERE clause. A version column is not necessary; the entire row information can be used for the update condition.

UPDATE optimistic
SET name = newName 
WHERE id = 1 AND name = originalName

Optimistic locking requires additional action when one thread fails, so it should be used when repeating the action is not a significant problem.
This is due to the assumption underlying optimistic locking, which assumes that conflicts are rare. Thus, it is suitable when conflicts are infrequent.

Optimistic Pessimistic
OpRes50 PeRes50

As you can see above, the response time is better for using optimistic locking in load tests with 50 threads. The maximum response time for optimistic locking is about 13 ms compared to 17 ms for pessimistic locking.

Therefore, it shows better performance when conflicts are rare, as it minimizes the overhead of managing locks and avoids blocking.

How about in the case of higher loads?
The results differ as the thread count increases to 500. Optimistic locking starts to emit errors, resulting in only 370 successful samples out of 500.

The throughput of optimistic locking is 123 per second, which is lower than pessimistic locking’s 166 per second. Most of the response times are under 14 ms for pessimistic locking (even though it lags much at first), while many response times for optimistic locking are over 15 ms.

Optimistic Pessimistic
Op500 Pe500
OpRes500 PeRes500

In real life, users who receive errors would retry, or retry logic would be implemented in the application, causing higher loads, which leads to slower response times and lower TPS.

Threads Result
500 Op500
2000 Op2000
3000 Op3000

As seen from the results, TPS peaks at 2000 threads (160 per second) and declines at 3000 threads (102 per second), which is even lower than at 500 threads (123 per second).

Optimistic locking could be a good option if you can predict that it would rarely fail, with relatively lower traffic, and retrying is not a significant issue.

Pessimistic locking could be used when traffic is relatively higher, or you do not want users to retry.

This article was created by Crocoder7. It is not to be copied without permission.

Leave a comment