Locking in Systems: Minimizing Contention for a Smoother Ride
When we talk about locking in databases, it’s like controlling access to specific data to ensure that everything stays consistent. But just like managing a crowd at a busy event, improper handling can lead to bottlenecks and delays. Imagine a fintech app where users frequently check balances, transfer funds, and view transaction histories. If we’re not careful with how we lock the database, this can lead to queues, slowdowns, and an overall poor experience.
Let’s explore how we can minimize these lock-related contentions using some practical strategies with sample database tables.
1. Reduce the Duration of Locks: Get in, Get Out Quickly
The key to minimizing contention is reducing how long a lock is held. The faster we can perform an operation and release the lock, the smoother the system will run.
A. Move Code Out of Synchronization
Consider a fintech application with three database tables:
In this setup, the users table handles authentication and other non-financial user information, such as email addresses or profile details. This table doesn’t need to lock the balances table when verifying a user’s login credentials. By moving this non-financial data out of the synchronization process, we avoid unnecessary locks, allowing multiple users to log in simultaneously without waiting.
B. Lock Stripping / Lock Splitting
Let’s say our app supports different types of financial operations, like checking the balance and transferring funds. Instead of locking the entire balances table every time a user performs any operation, we can split the locks. When a user checks their balance, we only lock the specific row in the balances table for that user. Meanwhile, transactions like fund transfers lock both the balances and transactions tables but only for the affected rows.
For example:
This method, known as lock splitting, ensures that different operations don’t block each other unnecessarily.
2. Replace Exclusive Locks with Coordination Mechanisms: Sharing is Caring
Sometimes, it’s not just about how long a lock is held but how you coordinate access to shared resources.
A. Read-Write Locks: A Balanced Approach
Imagine that multiple users want to check their balances simultaneously. Instead of locking the entire balances table, we can use a Read-Write Lock. This allows multiple users to read their balances at the same time, while only one user can update a balance at any given moment.
For example, the system lets all users read their balance from the balances table simultaneously. But when a user initiates a fund transfer, the system locks only the relevant row in the balances table, allowing the update to happen without affecting other users.
领英推荐
B. Atomic Variables: The Magic Pen
Let’s say we’re updating a counter for the number of transactions a user has performed. Instead of locking the entire transactions table, we use atomic variables. It’s like having a special pen that lets one user update the counter while others can still read it. This reduces the need for traditional locks and keeps the app responsive.
Two Ways of Locking Shared Resources: Which Path to Choose?
When dealing with databases, there are two main approaches to locking: Pessimistic and Optimistic. Your choice depends on the specific needs of your application.
A. Pessimistic Locking: The Traditional Approach
Pessimistic locking is like reserving a table at a restaurant before you arrive. In our fintech app, this would mean locking the user’s balance row in the balances table before starting any transaction process. The lock stays in place until the transaction is complete.
Pros:
Cons:
B. Optimistic Locking: A More Flexible Approach
Optimistic locking takes a more relaxed approach. The idea is to proceed with operations without locking initially, only checking for conflicts at the end. In our fintech app, this means updating the balance and only locking it when necessary.
For example:
Pros:
Cons: