One, foreword
- Before we look at pessimistic locks and optimistic locks, let’s take a look at what locks are and why they are used.
- Technology comes from life. Locks not only exist in programs, but also can be seen everywhere in reality. For example, the fingerprint lock we punch in to and from work, the password lock on the safe, and the user name and password we log in are also a kind of lock. The use of locks in life can protect our personal safety (fingerprint lock), property security (safe combination lock), information security (user name combination lock), let us more assured to use and life, because of the lock, we do not have to worry about personal property and information leakage.
- The lock in the program is a mechanism and means to ensure the security of our data. For example, when we have multiple threads to access and modify shared variables, we can syncronize the modification operation. When multiple users modify the same data in a table, we can lock the row (row lock). Therefore, when there is a possibility of concurrency in the program, we need to ensure the accuracy of the data in the case of concurrency, through this means to ensure that the current user and other users operating together, the result is the same as the result of his operation alone
- Poor concurrency control can result in dirty reads, phantom reads, and unrepeatable reads, as shown in the following figure:
Due to concurrent operations, if there is no concurrency control by locking, the final data in the database may be 3 or 5, resulting in inaccurate values
Pessimistic lock and optimistic lock
The first thing we need to understand is that both pessimistic locking and optimistic locking are defined by people and can be thought of as an idea.
2.1. Pessimistic lock
Pessimistic Lock: When you are Pessimistic, each time you fetch the data you think someone else will change it. So it locks up every time we pick up data. The shared resources in the pessimistic lock are only used by one thread at a time. Other threads block and transfer the resources to other threads when they are used up
In terms of efficiency, however, the mechanism for handling locking incurs additional overhead and increases the chance of deadlocks. It also reduces parallelism, because if A thread A has been locked, other threads must wait for that thread A to finish processing
Row locks, table locks, read locks (shared locks), write locks (exclusive locks), and syncronized implementations of the database are pessimistic locks
Pessimistic concurrency control is actually”Lock first and then access“To ensure the security of data processing,
2.2 optimistic locking
Optimistic Lock: Being so Optimistic that every time you go to get your data, you assume that no one else will change it. So it’s not locked, but if you want to update the data, before you update it, you check to see if someone else has changed the data between reading and updating it. If so, it reads again and tries to update again, repeating the above steps until the update succeeds (of course, it also allows the thread that failed to update to abandon the operation). Optimistic locking is suitable for multi-read application types, which improves throughput
In contrast to pessimistic locks, optimistic locks do not use the locking mechanism provided by the database when processing the database. Optimistic locking is usually implemented by logging versions of data or timestamps, but version logging is the most common.
Optimistic control believes that the probability of a data race between transactions is low, so it does it as directly as possible and does not lock until commit time, so there are no locks and deadlocks.
Three, the realization of the lock
Pessimistic locks block transactions, optimistic locks rollback retry: Each has its advantages and disadvantages, and one is not necessarily better than the other. Things like optimistic locking are good for low write situations, where collisions are really rare, which saves on the overhead of locking and increases the overall throughput of the system. However, if there are frequent conflicts, the upper layer application will constantly retry, which can degrade performance, so pessimistic locking is appropriate in this case.
3.1 Implementation of pessimistic lock
Scene:
User A and user B buy the same product in the same store, but the quantity of the product is only one
The following is the structure of t_goods and the data in the table:
Without locking, an error is reported if user A and user B place an order at the same time.
Pessimistic lock implementation, often rely on the locking mechanism provided by the database, in the database, how do we use pessimistic lock to solve this matter?
- Add when user A orders A product (stinky tofu), try to add pessimistic lock to the data (stinky tofu) first
- Lock failure: indicates that the item (stinky tofu) is being modified by another transaction, the current query needs to wait or throw an exception, the specific return method is up to the developer to define the case
- Lock success: modify the product (stinky tofu), that is, only user A can buy, user B wants to buy (stinky tofu) must wait. After user A buys the stinky tofu, user B will find that the quantity is already 0 when he wants to buy it. Then user B will give up after seeing it
- During this period, if there are other operations to modify or lock the data (stinky tofu), they will wait for us to unlock or directly throw an exception
So how do you add pessimism lock? Select * from MySQL where id=2; select * from MySQL where id=2; MySQL commits an update to the database as soon as it executes an update.
Select num from T_goods where id = 2 for update
We demonstrate this by opening two mysql sessions, i.e., two command lines:
A transaction is A:
We can see that the data can be queried immediately, num=1
Transaction B:
We can see that transaction B waits for transaction A to release the lock. If transaction A does not release the lock for A long time, transaction B will eventually report an error as follows:Lock wait timeout exceeded; try restarting transaction
, indicating that the statement is locked
Now let transaction A execute the command to modify the data, reduce the number of stinky tofu by one, then view the modified data, and commit to end the transaction
We can see that after the execution of transaction A, there are only 0 stinky tofu in stock. When user B comes to purchase this stinky tofu, he will find that the last stinky tofu has been purchased by user A, so user B can only give up buying stinky tofu.
Through pessimistic lock, we can solve the problem of selling goods out of stock due to the shortage of goods inventory.
3.1 Implementation of optimistic lock
For the above application scenario, how should we use optimistic lock to solve? SQL > alter table t_goods; alter table t_goods; alter table t_goods; alter table t_goods; alter table t_goods;
The specific operation steps are as follows:
1. Firstly, user A and user B find out the data of stinky tofu (ID =2) at the same time
2. Then user A buys first, and user A updates the data with (ID =1 and version=0) as the condition, changing the quantity to -1 and the version number to +1. The version number changes to 1. User A has now purchased the product
3. User B starts to buy, and user B also updates the data with (id=1 and version=0) as a condition
4. After the update, it is found that the number of updated data rows is 0, which means that someone has changed the data. At this point, user B should be prompted to review the latest data purchase
1, First we open two session Windows, enter the query statement:select num from t_goods where id = 2
A transaction is A:
Transaction B:
Transaction A and transaction B get the same data at the same time
2. Transaction A updates the data and then queries the updated data
At this point we can see that transaction A has been updated successfully and the inventory-1 version number +1 has been successfully updated
2. Transaction B updates the data and then queries the updated data
You can see that the final modification failed and the data did not change. At this point, we need to tell user B to reprocess
3.1.1 CAS
When it comes to optimistic locking, one concept must be mentioned: CAS what is CAS? Compare-and-swap, Compare and replace, there’s also something called compare-and-set, Compare and Set. 1. Compare: read A value A and check if the original value is still A (not changed by other threads) before updating it to B. 2. Setting: If yes, change A to B. No further action is required. [1] If not, do nothing. The above two steps are atomic and can simply be interpreted as instantaneous, which the CPU sees as a one-step operation. With CAS, you can implement an optimistic lock that allows multiple threads to read simultaneously (because there is no locking at all), but only one thread can successfully update the data, causing the other threads to rollback and retry. CAS uses CPU instructions to ensure atomicity of operations at the hardware level to achieve a lock-like effect.
The real CAS operation in Java calls the native method because there are no “lock” and “unlock” operations in the whole process, so optimistic locking strategy is also called lockless programming. In other words, optimistic locking is not a lock, it is simply an algorithm that retries CAS repeatedly, but CAS has an ABA problem. What is ABA problem, and how to solve it?
ABA question: If A variable V is first read with A value of A, and is still A value when it is ready to assign, can we say that its value has not been modified by other threads? Obviously not, because during that time its value could be changed to something else and then back to A, and the CAS operation would assume that it had never been changed. This problem is known as the “ABA” problem of CAS operations.
ABA problem solved: we need to add a Version number (Version), in each submission of the Version number +1 operation, then the next thread to submit changes, will bring the Version number to judge, if the Version is changed, then the thread retry or error message ~
Four, how to choose
Pessimistic locks block transactions, and optimistic locks rollback retry. Each has its advantages and disadvantages, and one is not necessarily better than the other. Things like optimistic locking are good for low write situations, where collisions are really rare, which saves on the overhead of locking and increases the overall throughput of the system.
However, if there are frequent conflicts, the upper layer application will constantly retry, which can degrade performance, so pessimistic locking is appropriate in this case.
Note:
1, optimistic lock does not really lock, so high efficiency. If the granularity of the lock is not well controlled, the probability of update failure is high, which leads to service failure.
2. Pessimistic locks rely on database locks and are inefficient. The probability of update failure is low.
Five, the summary
This article explains the difference between the pessimistic and optimistic locking, as well as the implementation scenario, either pessimistic or optimistic locking is defined the concept of people, is a kind of thought, how to have a friend with questions or problems may leave a message below, and the small farmers saw will first time reply you, thank you, everybody refuels ~