In the case of pessimistic locking, in order to ensure the isolation of transactions, it is necessary to lock reads consistently.
Lock the data when reading, and other transactions cannot change the data.
When changing or deleting data, it should also be locked. Other transactions cannot read these data.
In data caching, the data is usually read from the database and then put into the cache. Next, the data is read from the cache within the validity period of the cache to reduce the pressure on the database. However, in a highly concurrent environment, there may be problems. For example, take data from redis according to the specified format, but the current key does not exist, so you need to write data into it. If multiple processes request at the same time, it will cause secondary writing of data. If the logic is not complex, there will be no major problems. The problem is, if the data of this key will change? At this time, a lock mechanism needs to be added, that is, the process that obtains the lock permission is qualified to operate on the data.
(this means that a pessimistic lock is added to allow the process that gets the lock to determine the key operation. If there is one, it will be read. If there is no one, it will be written. When reading, other processes cannot change the data. If writing data, other transactions cannot read the data.)
When it comes to pessimistic locks, I first give a more vivid metaphor on the Internet
Take the gym as an analogy. There is a key (only one) hanging at the door. People who want to go in must get the key. People who get the key can enter, whether it’s warming up, drinking water or running. Until he comes out and hangs the key back on the wall, the next one can fight for it and go in again.
It sounds a little inhumane, so pessimistic locking is more suitable for strong consistency scenarios, but the efficiency is relatively low, especially the concurrency of reads. Optimistic locking is suitable for scenarios with more reads and fewer writes and fewer concurrent conflicts.
Implementation points and ideas
1. A task can only be held by one user in the same time period;
2. Avoid dead tasks, that is, avoid tasks being occupied by users for a long time and cannot be released. (using redis)
Set the key of a lock. Setnx is an atomic operation. Only one process can write successfully. A successful write returns true (indicating obtaining lock permission), and then the write content immediately releases the lock, that is, deletes the lock key.
If only the setnx command is used to set the lock, if the process holding the lock crashes or fails to delete the lock, other processes will not be able to obtain the lock, and the problem will be great.
The process that cannot obtain the lock determines the remaining effective time of the lock. If it is – 1, it means that the expiration time is not set, and the effective time of the lock is set to 5 seconds (5 seconds is reserved for the processing time of the process that obtains the lock, which is enough). Return true and wait for the lock to be deleted.
Set the value of the key to value only when the key does not exist.
If the key already exists, the setnx command does nothing.
keyThe value of is set to
value, and press the key
keyThe lifetime of is set to
keyAlready exists, then
SETEXThe command overwrites the existing value.
This work adoptsCC agreement, reprint must indicate the author and the link to this article