Original text: https://www.cnblogs.com/lr393993507/p/5909804.html
For the website we develop, if the website has a very large number of visits, then we need to consider the relevant Concurrent access problem. Concurrency problems are a headache for most programmers.
But then again, since we can’t escape it, let’s face it calmly~ Today let’s study the common problems together Concurrency and synchronization.
In order to better understand concurrency and synchronization, we need to first understand two important concepts: Synchronization and asynchronous
1. Synchronization and The difference and connection between asynchronous
The so-called synchronization can be understood as waiting for the system to return a value or message after executing a function or method. At this time, the program is blocked and can only receive Execute other commands only after receiving the value or message returned by
.
Asynchronous, after executing the function or method, you do not have to wait for the return value or message in a blocking manner. You only need to delegate an asynchronous process to the system, then when the system receives the return
value or When sending a message, the system will automatically trigger the delegated asynchronous process to complete a complete process.
Synchronization can be regarded as a single thread to a certain extent. After this thread requests a method, it will wait for the method to reply to it, otherwise it will not continue execution (dead-hearted) .
Asynchronous can be regarded as multi-threading to a certain extent (nonsense, how can a thread be called asynchronous). After requesting a method, it will be ignored and continue to execute other methods.
Synchronization is one thing, done one thing at a time.
Asynchronous means doing one thing without causing other things to be done.
For example: eating and talking can only happen one at a time, because there is only one mouth.
But eating and listening to music are asynchronous, because listening to music does not cause us to eat.
For Java programmers, we will often hear the synchronization keyword synchronized. If the synchronized monitoring object is a class, then if an object
accesses the If the method is synchronized, then if other objects want to continue to access the synchronized method in the class, they will enter blocking. Only after the previous object
finishes executing the synchronized method can the current object continue to execute. this method. This is synchronization. On the contrary, if there is no synchronization keyword modification before the method, then different objects
can access the same method at the same time, which is asynchronous.
To add (related concepts of dirty data and non-repeatable reading):
Dirty data
Dirty reading means that when a transaction is accessing data, and The data has been modified, but the modification has not yet been submitted to the database. At this time, another transaction also accesses the data and then uses the data.
Because this data has not yet been committed, the data read by another transaction is dirty data, and operations based on dirty data may be incorrect.
Non-repeatable read
Non-repeatable read refers to reading the same data multiple times within a transaction. Before this transaction ends, another transaction also accesses the same data. Then, between the two data reads in the first transaction, due to the modification of the second transaction, the data read twice by the first transaction may be different. In this way, the data read twice within a transaction is different, so it is called non-repeatable read
2. How to deal with concurrency and synchronization
Today we will talk about how to deal with concurrency and synchronization issues mainly through the lock mechanism.
We need to understand that the lock mechanism has two levels.
One is at the code level, such as the synchronization lock in Java. The typical synchronization keyword is synchronized. I will not explain too much here.
If you are interested, you can Reference: http://www.cnblogs.com/xiohao/p/4151408.html
The other is at the database level, the more typical ones are pessimistic locking and optimistic locking. What we focus on here is pessimistic locking (traditional physical locking) and optimistic locking.
Pessimistic Locking:
Pessimistic locking, as its name suggests, refers to the locking of data by the outside world. (Including other current transactions in this system, as well as transaction processing from external systems) modifications are conservative. Therefore,
the data is locked during the entire data processing process.
The implementation of pessimistic locking often relies on the locking mechanism provided by the database (only the locking mechanism provided by the database layer can truly guarantee the exclusivity of data access, otherwise, even in this system
Even if the locking mechanism is implemented, there is no guarantee that external systems will not modify the data).
A typical pessimistic lock call that relies on the database:
select * from account where name=”Erica” for update
This SQL statement locks the account All records in the table that match the search criteria (name=”Erica”).
Before this transaction is submitted (the lock during the transaction will be released when the transaction is submitted), the outside world cannot modify these records.
Hibernate’s pessimistic lock is also implemented based on the database locking mechanism.
How do servlets match together? Please search the servlet documentation. This is not nonsense, many people think that the matching method /xyz/*.do can be effective.
If you still don’t know how to write a servlet, then please search how to write a servlet. This is no joke. Today, with various integration tools flying around, many people will not write it from scratch. A servlet.
3. Basic solution introduction
Among them, for the URL Rewriter part, you can use paid or open source tools to implement it. If the URL It’s not particularly complicated. You can consider implementing it in a servlet, so it looks like this:
Summary: In fact, we rarely consider this kind of issue during development, and we just implement the function first. , when a programmer works for 1 to 2 years, he will feel that implementing functions is not the most important thing. Safety performance, quality, etc. are what a developer should care about most. What I’m talking about today is high concurrency.
My solution is:
1. Adopt distributed application design
2. Distributed cache database
3. Code Optimization
Example of high concurrency in Java:
The specific situation is as follows: Through java and database, you can realize the automatic growth of the sequence yourself.
The implementation code is roughly as follows:
id_table table structure, main fields:
id_name varchar2(16);
id_val number(16,0);
id_prefix varchar2(4);
//Operation DB
public synchronized String nextStringValue(String id){
SqlSession sqlSess = SqlSessionUtil.getSqlSession();
sqlSess.update(“update id_table set id_val = id_val + 1 where id_name=”+id);
Map map = sqlSess. getOne(“select id_name, id_prefix, id_val from id_table where id_name=”+ id);
BigDecimal val = (BigDecimal) map.get(“id_val”);
// id_val is a specific number, rePack mainly returns a fixed-length string uniformly; such as: Y0000001, F0000001, T0000001, etc.
String idValue = rePack(val, map);
return idValue ;
}
//Public method
public class IdHelpTool{
public static String getNextStringValue(String idName){
return getXX().nextStringValue(idName);
}
}
Specific users use methods similar to this: IdHelpTool. getNextStringValue(“PAY_LOG”); to call.
Problems:
(1) When concurrency occurs, duplicate IDs are sometimes obtained;
(2) Because the server has made some relevant settings, sometimes calling this method seems to cause a timeout. .
In order to solve problem (1), I have considered adding synchronized to the method getNextStringValue. If there are too many synchronized keywords, will it cause a timeout?
I beg you to give me a general idea to solve the problem! ! !
Solution 1:
1. Recommend https://github.com/adyliu/idcenter
2. It can be implemented through third-party redis.
Solution 1:
1. Duplicate IDs occur because of dirty reads. For example, if synchronized is not added during concurrency, problems may occur
2. But synchronized is added , the performance has dropped sharply. Java itself is multi-threaded. It is not a wise choice to use it in a single thread. At the same time, if synchronized is added during distributed deployment, concurrency cannot be controlled
3. Call this method , if a timeout occurs, it means that your concurrency has exceeded the limit that the database can handle, and the database will wait indefinitely and cause timeout
Based on the above analysis, it is recommended to use the thread pool solution. Alipay’s order number is the thread pool used. program was carried out.
The database update does not add 1 at a time, but adds hundreds or even thousands at a time. Then the 1,000 serial numbers obtained are placed in the thread pool and slowly allocated. It can cope with any large concurrency while ensuring There is no pressure on the database.