Lock Modes: Shared and Exclusive Locks

Lock modes define what concurrent transactions are allowed to do with data protected by a lock. The two fundamental modes are Shared (S), which supports compatible reads, and Exclusive (X), which provides sole access for modification.

A Shared lock (`S`) is typically acquired when a transaction needs to read locked data under a pessimistic concurrency-control scheme. Multiple transactions can hold compatible Shared locks on the same resource, so readers can often proceed concurrently. Whether a particular database takes or retains such locks depends on its isolation level and implementation.

An Exclusive lock (`X`) is used when a transaction needs to modify a locked resource. An Exclusive lock conflicts with both Shared and Exclusive locks, preventing other transactions from acquiring incompatible access until the lock is released. This protects a write from conflicting concurrent operations.

Lock compatibility is the key idea to remember. Shared versus Shared is normally compatible, while Shared versus Exclusive and Exclusive versus Exclusive are incompatible. A transaction waiting for an incompatible lock may block until the holder releases it, which can affect throughput and latency.

In Java backend systems, the application may encounter these semantics through a database or ORM rather than manipulating database locks directly. For example, JPA provides pessimistic lock modes such as `PESSIMISTIC_READ` and `PESSIMISTIC_WRITE`, while the exact SQL locking behavior is database-dependent. Lock modes should therefore be discussed together with transaction boundaries, isolation, and the specific database implementation.

Key points

Interview questions

What is the difference between a Shared lock and an Exclusive lock?

A Shared lock is generally used for reading and can coexist with other compatible Shared locks. An Exclusive lock is used for modification and conflicts with both Shared and Exclusive locks. Therefore, multiple readers may proceed together, while a writer requires exclusive access to the protected resource.

Why does an Exclusive lock conflict with a Shared lock?

A modification must not race with another transaction that is accessing the same protected data under incompatible assumptions. By making X incompatible with S, the locking system prevents a transaction from modifying a resource while another transaction holds a conflicting read lock. This creates a defined serialization point for conflicting operations.

How do pessimistic and optimistic locking differ?

Pessimistic locking assumes conflicts are possible and uses locks to restrict concurrent access before the conflict occurs. Optimistic locking generally allows concurrent work and checks for a conflict when an update is committed, often using a version column. Pessimistic locking can cause blocking, whereas optimistic locking commonly trades blocking for conflict detection and retry handling.

How do JPA pessimistic lock modes relate to database locks?

JPA exposes pessimistic lock modes such as `PESSIMISTIC_READ` and `PESSIMISTIC_WRITE` so an application can request locking semantics through the persistence layer. The persistence provider translates those requests into database-specific operations. Consequently, the exact lock acquired, waiting behavior, and supported modes depend on the database, driver, provider, and transaction configuration. A strong answer should distinguish the JPA abstraction from the database's actual locking implementation.

What problems can excessive pessimistic locking cause in a backend service?

Long-held locks can increase contention and cause transactions to wait, reducing throughput and increasing latency. Poorly ordered locking can also create deadlocks, where transactions wait on one another indefinitely until the database detects and resolves the cycle. Backend code should therefore keep transactions appropriately scoped, acquire resources consistently where possible, and have a strategy for transient failures and retries.