2

For enterprise applications, it is basically impossible to not involve concurrency at all. Because a lot of things in an application are going on at the same time. Concurrency can occur in data fetching, service invocation, and even user interaction. There are two important solutions to the concurrency problem, one is isolation and the other is immutability.

Concurrency problems will occur when multiple execution units access the same resource at the same time. In this case, a good way is to divide the "cake" so that each execution unit can access its own resources. Good concurrency design is: Find a way to create a good isolation zone, and then analyze the workflow to make the isolation zone complete as many tasks as possible.

Concurrency problems can arise where shared data can change. Starting from the actual scene, when two customers ask the two waiters whether they have a certain item at the same time, the two waiters each check the system and reply that the customer still has one. One of the two customers must be disappointed. Then the solution to this matter is to add a quarantine area (shopping cart), and the waiter will notify the user when the current item is successfully placed in the customer's shopping cart, and then the failed party can inform the user that the item has been sold out. Although there is the possibility of returning the purchased users, it is undoubtedly much better than the previous result. This is the pessimistic lock mentioned below.

Let's start by introducing two concurrency control strategies:

optimistic and pessimistic concurrency control

In a certain system, two enterprise employees A and B want to edit the same user information at the same time. At this time, both A and B have obtained the user's information data. Then the two of them make changes, and Employee A completes and commits first. Then employee B completes the operation and submits it. At this time, the user information in the system only retains the data provided by B, and discards the data of employee A. This can cause unforeseen problems and possibly even cause them to lose their jobs. Although the operation log can be used to trace which employee manipulated the data, this information is meaningless because the system does not let any employee know about the modification.

When some variable data cannot be isolated, we can use two different control strategies: optimistic locking strategy and pessimistic locking strategy. Optimistic locking is used for conflict detection and pessimistic locking is used for conflict avoidance.

The pessimist strategy is very simple. When user A obtains user information, the system locks the current user information, and then user B will be informed that others are editing when obtaining user information. The system does not allow employee B to access the data until employee A submits it. At this time, B obtains the updated data of A.

The optimist strategy does not impose any restrictions on access. At this time, we can add a version number to the user information to inform the user that the information has been modified. Optimistic locking requires that each piece of data has a version number, and the version number is updated when the data is updated. For example, employee A submits the current version number when updating user information. The system judges that the version number submitted by A is consistent with the version number of the piece of information, and allows the update. Then the system will modify the version number. When employee B submits, he will carry the previous version number. At this time, the system judges that it fails and asks B to re-obtain the data and version number, and then submit it again.

The selection criteria for optimistic locking and pessimistic locking are: the frequency and severity of conflicts. If the result of the conflict is unacceptable to the user, we can only adopt a pessimistic locking strategy. If the results of conflicts are not severe, or the frequency is low, we can choose optimistic locking, which is easier to implement and has better concurrency.

Of course, we can also optimize the optimistic lock by adding the update time (as the version number) and the update user to the information, so that the system can inform the B employee that the information has been modified, and when and who operated it. . The system can also provide B a new update time and a choice of whether to force the update. Of course, it is even possible to inform employee B of the previously modified information based on business requirements and log information.

deadlock

A particular problem with using pessimistic locking techniques is deadlocks, where users want to acquire more locks when they have already acquired them. Taking the problem of the first two customers, fruitcake needs to get fruit and cake. Two users each have one of them and expect to get each other's things.

The solution to deadlock is detection processing and timeout control.

The check process will detect that a deadlock has occurred and will choose a "victim" who will give up what he has to guarantee that another client can get the fruitcake. The timeout control is to add a timeout period to each lock. Once the timeout period is reached, the items in the current shopping cart will be cleared.

Timeout control and detection mechanisms are used when a deadlock has occurred, and another approach is to avoid deadlocks. The way to prevent deadlock is to acquire all the locks that may be needed when the user acquires the lock, coarse-strength lock (this is conservative, but very effective), that is, fruitcake is not composed of two items.

A coarse-strength lock is a single lock that covers multiple resources, which simplifies the complexity of multiple locks. This actually occurs in the process of optimistic locking, such as users and user-related address information. If the user address information is modified, the user information will also be changed, so how to obtain and set optimistic locks? We need to find the core of a set of resources.

At the same time, finding the core of a set of resources will also make the development code logic clearer. You may think about it, in the operation at the database level, is it better to choose the logical sequence of updating the sub-table first and then the main table, or is it better to update and modify the main table as the entry?

encourage

If you think this article is good, I hope you can give me some encouragement and help to star it under my github blog.

blog address


jump__jump
2.5k 声望4k 粉丝

猎奇者...未来战士...very vegetable