Understanding Pessimistic Locking and Optimistic Locking in PostgreSQL

Pessimistic locking and optimistic locking are two approaches used in database management systems, including PostgreSQL, to control concurrent access to shared data.

Pessimistic Locking:

Pessimistic locking is a concurrency control mechanism that assumes conflicts will occur and locks data preemptively to prevent conflicts. When a transaction acquires a pessimistic lock on a piece of data, other transactions are blocked from accessing the data until the lock is released. Pessimistic locking can be implemented using shared locks, exclusive locks, or other types of locks.

For example, imagine that two users are attempting to update the same row in a table in a PostgreSQL database. With pessimistic locking, one of the transactions would acquire an exclusive lock on the row before making changes, preventing the other transaction from making changes to the row until the lock is released.

Optimistic Locking:

Optimistic locking is a concurrency control mechanism that assumes conflicts are rare and does not lock data preemptively. Instead, when a transaction attempts to modify a piece of data, it checks if the data has been modified by another transaction since it was last read. If the data has not been modified, the transaction can proceed with the update. If the data has been modified, the transaction is rolled back, and an error is returned to the application.

For example, imagine that two users are attempting to update the same row in a table in a PostgreSQL database. With optimistic locking, each transaction would read the current version of the row before making changes. When the first transaction attempts to commit the changes, it checks if the row has been modified by the other transaction. If the row has not been modified, the first transaction commits the changes. If the row has been modified, the first transaction rolls back, and the application is notified of the conflict.

Impact on Performance:

Both pessimistic and optimistic locking have trade-offs that can impact PostgreSQL performance. Pessimistic locking can be more reliable and prevent conflicts from occurring, but it can also lead to more blocking and reduced concurrency. Optimistic locking can be more efficient and allow for higher concurrency, but it can also lead to more conflicts and transaction rollbacks.

In general, it’s important to choose the appropriate locking mechanism based on the specific requirements of the application and the characteristics of the data being accessed. For example, if conflicts are rare and high concurrency is a priority, optimistic locking may be a good choice. On the other hand, if conflicts are common and data consistency is critical, pessimistic locking may be a better option. It’s also important to monitor and optimize locking mechanisms to prevent performance bottlenecks and ensure optimal database performance.

Example

Here is an example SQL program that can be used to monitor PostgreSQL locking:

SELECT
COALESCE(pg_stat_activity.application_name, ‘<backend>’) AS source,
COALESCE(pg_stat_activity.query, ‘<none>’) AS query,
COALESCE(EXTRACT(EPOCH FROM (now() – pg_stat_activity.query_start)), 0) AS duration,
COALESCE(pg_stat_activity.query_state, ‘<none>’) AS state,
COUNT(*) AS count
FROM pg_stat_activity
WHERE
pg_stat_activity.query_state <> ‘idle’
AND pg_stat_activity.query NOT LIKE ‘%pg_stat_activity%’
GROUP BY 1, 2, 3, 4
ORDER BY 5 DESC, 3 DESC;

This SQL program uses the pg_stat_activity view to identify active queries that are waiting on locks. It shows the source of the query (i.e. the application name or backend process), the query itself, the duration of the wait time in seconds, the state of the query, and the count of occurrences for each unique combination of these fields.

This output shows that there are several queries waiting on locks (state = waiting) for various durations. These queries are grouped by their source and query, and sorted by the count of occurrences in descending order. This information can be used to identify and diagnose performance issues related to locking and concurrency in PostgreSQL.

About Shiv Iyer 422 Articles
Open Source Database Systems Engineer with a deep understanding of Optimizer Internals, Performance Engineering, Scalability and Data SRE. Shiv currently is the Founder, Investor, Board Member and CEO of multiple Database Systems Infrastructure Operations companies in the Transaction Processing Computing and ColumnStores ecosystem. He is also a frequent speaker in open source software conferences globally.