For the site we’re developing, if the site gets a lot of traffic, then we need to consider the concurrency issues. Concurrency is a headache for most programmers, but let’s face it. Today, let’s take a look at common concurrency and synchronization. To better understand concurrency and synchronization, we need to understand two important concepts:
Synchronous and asynchronous
1. The difference and connection between synchronous and asynchronousThe so-called synchronization can be understood as waiting for the system to return a value or message after the execution of a function or method. At this time, the program is blocked and can only execute other commands after receiving the returned value or message. Asynchronous: After the function or method is executed, there is no need to wait for the return value or message obstructively, but only need to entrust an asynchronous process to the system. Then when the system receives the return value or message, the system will automatically trigger the entrusted asynchronous process to complete a complete process.
Synchronization can be thought of to some extent as a single thread, in which a thread requests a method and waits until that method replies to it, but does not proceed. Asynchrony can be thought of to some extent as multi-threaded (crap, what is asynchrony for a thread?), requesting a method, then leaving it alone and continuing to execute other methods. Synchronization is one thing, one thing at a time. Asynchrony means doing one thing without being prompted to do something else. For example, eating and talking can only be done one at a time because there is only one mouth. But eating and listening to music are asynchronous, because listening to music doesn’t make us eat. For Java programmers, we often hear about the synchronized keyword. If the monitored object is a class, then if one object accesses a synchronized method in the class, other objects will block if they attempt to access the synchronized method in the class. The current object cannot continue executing the synchronized method until the previous object has finished executing it. That’s synchronization. On the other hand, if a method is not preceded by a synchronization keyword, then different objects can access the same method at the same time, which is asynchronous. As a side note: Dirty data dirty reads are when a transaction is accessing data and making changes to the data that have not been committed to the database, and then another transaction is accessing the data and using the data. Because this Data is uncommitted Data, another transaction reads the Data as Dirty Data, which may not be correct. Non-repeatable Read Non-repeatable read means that the same data is read multiple times in a transaction. The same data is accessed by another transaction while the transaction is still active. Then, between the two reads in the first transaction, the data read by the first transaction may not be the same because of the modifications made by the second transaction. This happens when the data read twice in a transaction is not the same and is therefore called a non-repeatable read
2. How to handle concurrency and synchronization
Today’s discussion of how to deal with concurrency and synchronization is mainly through locking mechanisms. We need to understand that the locking mechanism has two layers. One is at the code level, such as the Java lock, which is typically synchronized. I won’t go into too much detail here. Interested can refer to: http://www.cnblogs.com/xiohao/p/4151408.html is another database level, typically is pessimistic and optimistic locking. Here we focus on pessimistic locks (traditional physical locks) and optimistic locks.
Pessimistic locks:Pessimistic locking, as its name suggests, refers to the conservative attitude towards data being modified by outside parties (including other current transactions on the system, as well as transactions from outside the system), and thus keeping the data locked for the entire data processing process. The realization of pessimistic lock often relies on the locking mechanism provided by the database (only the locking mechanism provided by the database layer can truly ensure the exclusivity of data access, otherwise, even if the locking mechanism is implemented in this system, it cannot guarantee that the external system will not modify the data). A typical pessimistic lock call that relies on a database: Select * from account where name= “Erica” for update lock all records in the account table that match the search criteria (name= “Erica”). These records cannot be modified by outsiders until the transaction commits (when locks are released during the transaction). Hibernate pessimistic lock, also based on the database lock mechanism implementation. String hqlStr =”from TUser as user where user.name=’Erica'”; Query query = session.createQuery(hqlStr); query.setLockMode(“user”,LockMode.UPGRADE); List userList = query.list(); Query. SetLockMode Locks the records of the specified alias in the query (we specified an alias “user” for the TUser class), in this case, locks all user records returned. Observe the SQL statements generated by Hibernate at runtime: select tuser0_.id as id, tuser0_.name as name, tuser0_.group_id as group_id, tuser0_.user_type as user_type, Tuser0_. Sex as sex from t_user tuser0_ WHERE (tuser0_. Name =’Erica’) for update Clause implements the pessimistic locking mechanism. Hibernate has the following locking modes: ø LockMode.NONE: No locking mechanism. WRITE: Hibernate automatically obtains lockmode. READ: Hibernate automatically obtains lockmode. WRITE: Hibernate automatically obtains lockmode. READ: Hibernate automatically obtains records when it reads them. The above three locking mechanisms are generally used by Hibernate internally. For example, Hibernate automatically locks the target object in the save method to ensure that the object will not be modified by the outside world during the Update process. ø lockmode. UPGRADE: Use the for update clause of the database to lock. ø lockmode. UPGRADE_NOWAIT: A specific implementation of Oracle that uses Oracle’s for Update nowait clause to implement locking. The above two locking mechanisms are commonly used in the application layer. Locking is generally implemented through the following methods: Criteria. SetLockMode query.setlockmode session. lock Note that the lock is only set before the Query starts (that is, before the SQL for Hiberate is generated). Otherwise, The data has already been loaded through Select SQL without the for UPDATE clause, and database locking is out of the question. To better understand select… Mysql > update table lock (); mysql > update table lock (); The basic structure of a table is as follows:



The contents of the table are as follows:



Open two test Windows, execute select * from ta for update0 in one window and perform update in the other window as shown in the following figure:



Wait until a window commit to look like this:



Note that for update is placed in a mysql transaction, either begin or commit. As to lock the entire table or lock the selected row, please refer to: http://www.cnblogs.com/xiohao/p/4385768.html for the pessimistic locks is simple to use hibernate, here can’t write demo ~ yourself interested in check with respect to ok ~

Optimistic Locking:Compared with pessimistic locking, optimistic locking mechanism adopts a looser locking mechanism. Pessimistic locking is mostly implemented by the locking mechanism of the database to ensure maximum exclusivity of operations. However, the resulting database performance costs, especially for long transactions, are often prohibitive. As a financial system, when an operator to read the user’s data, and on the base of read user data aspirant row change (e.g., change user account balances), when if use pessimistic locking mechanisms, which means the entire operating process (read data from the operator and began to change, and even commit changes the results, the whole process of Database records are always locked, and you can imagine the consequences of this situation if you have hundreds or thousands of concurrent requests. Optimistic locking solves this problem to some extent. Optimistic locking, mostly based on data Version) recording mechanism implementation. What is data version? Adding a version identifier to the data is typically done by adding a “Version” field to the database table in a database table-based version solution. This version number is read with the data when it is read, and is incremented with the version number when it is updated later. In this case, the version of the submitted data is compared with the current version of the database table. If the version of the submitted data is greater than the current version of the database table, the submitted data is updated. Otherwise, the submitted data is considered to be expired. For the example above of modifying user account information, assume that there is a version field in the account information table in the database with the current value of 1; The current account balance field (balance) is $100. Operator A then reads it out (version=1) and deducts $50 ($100-$50) from its account balance. 2 During operator A’s operation, Operator B also reads this user information (version=1) and deducts $20 ($100-$20) from its account balance. 3 Operator A completed the modification and added one (version=2) to the data version number, together with the balance after account deduction (balance=$50), and submitted the data to the database for update. At this time, as the submitted data version is larger than the current version recorded in the database, the data is updated. Database record version is updated to 2. 4 Operator B completed the operation and added the version number by one (version=2) in an attempt to submit data data to the database (balance=$80). However, when comparing the version of the database record, it was found that the version number of the data submitted by operator B was 2, and the current version of the database record was also 2. Operator B’s submission is rejected because the optimistic locking policy of “commit version must be greater than the current version to perform the update” is not met. In this way, the possibility of operator B overwriting operator A’s operation results with modified results based on older data version=1 is avoided. As can be seen from the above example, the optimistic locking mechanism avoids the overhead of database locking in long transactions (both operator A and operator B do not lock database data during operation), which greatly improves the overall performance of the system under large concurrency. It is important to note that the optimistic locking mechanism is often based on the data stored in the system logic, therefore also have a certain bureau limition, such as in the example above, because the optimistic locking mechanism is implemented in our system, from external system user balance update operation is not controlled by our system, thus may cause dirty data is updated in the database. In the system design stage, we should fully consider the possibility of these situations and make corresponding adjustments (such as implementing optimistic locking policy in the database stored procedure, opening only the data update path based on this stored procedure to the public, rather than directly opening the database table). Hibernate has an optimistic lock implementation built into its data access engine. If we do not need to consider the external system database update operation, using the transparent optimistic lock implementation provided by Hibernate will greatly improve our productivity.



Note that the version node must appear after the ID node. Here we declare a version attribute to store the version information of the User, which is stored in the version of the User table. The optimize-lock attribute has the following optional values: ø None optimistic lock ø Version optimistic lock by version mechanism ø Dirty optimistic lock by checking the changed attributes ø all optimistic lock by checking all attributes of the optimistic lock mechanism through version is Hibernate Optimistic locking is officially recommended, and is currently the only mechanism in Hibernate that still works even when the data object is modified after leaving the Session. Therefore, we generally choose the Version approach as the Hibernate optimistic lock implementation mechanism. 2. The configuration files hibernate.cfg. XML and UserTest test classes hibernate.cfg.xml



UserTest.java



Each time we update TUser, we can see that the version in the database is increasing. We will use optimistic locking to implement concurrent and synchronous test cases: here we need to use two test classes, one on different virtual machines, to simulate multiple users working on a table at the same time, and one of the test classes needs to simulate a long transaction, usertest.java



UserTest2.java



Start usertest2. Java test class, execute to thread. sleep(10000); This statement causes the current thread to go to sleep. In less than 10 seconds

Start the UserTest class and at 10 seconds we will throw the following exception in usertest.java:



UserTest2 code will be thrown at tx.com MIT () often StaleObjectStateException, and points out that the version check failed, the current transaction is trying to submit an expiration data. By catching this exception, we can handle the failure of optimistic lock verification

3. Analysis of common concurrent synchronization cases

Case 1: Booking system case, a certain flight has only one ticket, suppose 1W people open your website to book, ask you how to solve the concurrency problem (can be extended to any high concurrency site to consider

Concurrent read and write problems of

The problem is that 1W people come to visit, and we need to make sure that everyone can see the tickets before they go out. It’s impossible for one person to see the tickets while others can’t see them. Who can grab it depends on the person’s “luck”

Speed, etc.)

Second consideration of the problem, concurrent, 1W people click to buy at the same time, who can clinch a deal? There is only one ticket in all.

First, it is easy to think of several schemes related to concurrency:

Lock synchronization refers more to the application level, where multiple threads come in and can only be accessed one by one. This is syncrinized in Java. Locks also have two layers, one of which is discussed in Java

Like locks, used for thread synchronization; Another layer is database locking; If the system is distributed, the only obvious way to do this is to use database side locks.

Assuming we use synchronization mechanism or database physical locking mechanism, how to ensure that 1W people can see tickets at the same time, obviously will sacrifice performance, is not desirable in the high concurrency website. After using Hibernate, we

Another concept is proposed: optimistic lock, pessimistic lock (that is, traditional physical lock);

Optimistic locking solves this problem. Optimistic locking means that without locking the table, the use of business control to solve the concurrency problem, so as to ensure the concurrent readability of data and ensure the exclusivity of saved data

It also solves the problem of dirty data caused by concurrency.

How to implement optimistic locking in Hibernate

Prerequisite: Add a redundant field to the existing table, version version number, type long

Principle:

1) Only current version number = database table version number can be submitted

2) After the submission, the version number is Version ++

The implementation is simple: add an attribute in orMapping called optimize-lock =”version”. Here is a sample snippet

<hibernate-mapping>

<class name=”com.insigma.stock.ABC” optimistic-lock=”version” table=”T_Stock” schema=”STOCK”>

Case two, stock trading system, banking system, large amount of data how do you consider

First of all, the stock exchange system’s quotation table, every few seconds there will be a quotation record, a day down (assuming the quotation 3 seconds a) number of stocks ×20×60*6 records, a month down this table records

The amount? If the number of records in an Oracle table exceeds 100W, the query performance deteriorates. How to ensure system performance?

For example, China Mobile has hundreds of millions of users, how to design the table? Do all applications exist in one table?

Therefore, a large number of systems must consider table split – (table name is different, but the structure is exactly the same), several common ways :(depending on the case)

1) According to the business points, such as the table of mobile phone number, we can consider the table starting with 130 as one table, the other table starting with 131 and so on

2) Use Oracle’s table splitting mechanism to make table splitting

3) If it is a trading system, we can consider splitting it according to the timeline, with daily data in one table and historical data in other tables. The report and query of historical data here will not affect the trading of the day.

Of course, after the table split our application has to do the corresponding adaptation. Simple OR-mapping may have to change. For example, part of the business has to go through stored procedures

In addition, we have to consider caching

By caching, I’m not just referring to Hibernate. Hibernate itself provides level 1 and level 2 caching. The cache here is application independent and still memory reads, if we can reduce the frequency of database visits

Q: That must be great for the system. For example, in the commodity search of an e-commerce system, if the commodities of a certain keyword are frequently searched, this part of the commodity list can be considered to be stored in the cache (memory)

Go to), so that you do not need to visit the database every time, performance greatly increased.

A simple cache can be interpreted as creating a hashmap for yourself, and creating a key for the frequently accessed data. The value is the value searched from the database for the first time, and can be read from the map for the next time

Read database; The professional ones now have separate caching frameworks such as memcached, which can be deployed as a cache server.

4, common means to improve the efficiency of high concurrency access

First of all, what are the bottlenecks of high concurrency?

1. The server network bandwidth may be insufficient

2. The number of Web threads may be insufficient

3. The database connection query may fail.

According to different situations, the solution is also different.

  1. Like the first case, which can increase network bandwidth, DNS domain name resolution distributes multiple servers.
  2. Load balancing, front proxy server nginx, Apache, etc
  3. Database query optimization, read and write separation, table and so on

Finally, copy something that needs to be handled frequently under high concurrency:

  • Try to use cache, including user cache, information cache, etc., spend more memory to do cache, can greatly reduce the interaction with the database, improve performance.
  • Use tools such as Jprofiler to identify performance bottlenecks and reduce additional overhead.
  • Optimize database query statements to reduce directly generated statements using tools such as Hibernate (only long queries are optimized).
  • Optimize database structure, do more index, improve query efficiency.
  • Statistical functions should be cached as far as possible, or related reports should be collected on a daily basis or at regular intervals to avoid statistical functions when needed.
  • Use static pages wherever possible and minimize container parsing (try to generate static HTML to display dynamic content).
  • After solving the above problems, use a server cluster to solve the bottleneck problem of a single server.

Java high concurrency, how to solve the problem

Before I’ll high concurrency solutions is mistaken for thread or queue can be solved, because when high concurrency is a lot of users in access, lead to the phenomenon of system data is not correct, the loss of data, so think of solve with the queue, queue actually solve way can also processing, such as we in the auction goods, forward comment on weibo or kill goods, etc., At the same time, the traffic is particularly large, the queue plays a special role in this, put all requests into the queue, millisecond timing units, orderly, so that there will not be data loss system data is incorrect.

Today, I have checked the information, there are two solutions to high concurrency:

One is to use caching and the other is to generate static pages. There is also from the most basic place to optimize our code to reduce unnecessary waste of resources 🙁

1. Avoid frequent new objects and use the singleton pattern for classes that require only one instance in the entire application. For String concatenation, use StringBuffer or StringBuilder. Classes of utility type are accessed through static methods.

2. Avoid using wrong methods. For example, Exception can control method rollout, but Exception should retain stackTrace consumption performance. Using efficient JAVA classes such as ArrayList performs better than Vector.

First of all, I haven’t used the cache technology, I think I should is when the user requests the data stored in the cache, the next request when testing the cache data does exist, prevent multiple requests the server, results in the decrease of server performance, serious cause server crash, it is just my own understanding, detailed information is needed on the Internet collecting;

Used to generate a static page I don’t think we should model, we have seen many sites when the requested page after the has changed, such as “http://developer.51cto.com/art/201207/348766.htm” to the page request is actually a server address, after conversion to HTM, Access speeds increase because static pages have no server components; Here I would like to introduce more:

First, what is page static:

Simply put, if we visit a link, the server’s corresponding module will process the request, go to the corresponding JSP interface, and finally generate the data we want to see. The downside is obvious: because the server processes every request, if there are too many high-concurrency requests, the application server will be stressed and the server will be brought down. So how to avoid it? Wouldn’t the application server be less stressed if we saved the result of the test.do request to an HTML file that the user accessed each time?

So where do static pages come from? We can’t do every page manually, can we? This is where we get to, static page generation… What we need is to generate static pages automatically. When the user visits, test.html will be generated automatically and displayed to the user.

Two, the following is a brief introduction to the knowledge points we should master in order to master the page static scheme:

1, basic – URL Rewrite

What is URL Rewrite? The URL rewrite. To illustrate, a simple example: if you type in the URL, but you actually visit abc.com/test.action, you can say that the URL has been rewritten. This technique is widely used, and there are many open source tools that can do this.

2. Basics – Servlet web.xml

If you don’t know how a request and a servlet match up in web.xml, search the servlet documentation. This is not nonsense. There are many people who think that /xyz/*.do matches work.

If you don’t know how to write a servlet, do a search on how to write a servlet. This is not a joke. In today’s world of integrated tools, many people will not write a servlet from scratch.

Iii. Basic scheme introduction



The URL Rewriter part can be implemented using paid or open source tools. If THE URL is not particularly complex, it can be implemented in servlets, which looks like the following:



Summary: in fact, we rarely consider this problem in the development, are directly the first function implementation, when a programmer in the work to 1 or 2 years, will feel that the light implementation function is not the most important, safety performance, quality and so on is a developer the most concerned. Today I’m talking about high concurrency.

My solution:

1. Adopt distributed application design

2. Distributed cache database

3. Code optimization

Examples of high concurrency in Java:

✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈

Here’s how it works: Implement automatic sequence growth yourself, using Java and a database.

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);



Specific users, it is through such way: IdHelpTool. GetNextStringValue (” PAY_LOG “); To invoke.

Question:

(1) When concurrency occurs, duplicate ids are sometimes obtained;

(2) Sometimes calling this method seems to cause a timeout due to some setup done by the server.

In order to solve the problem (1), I have considered adding synchronized to getNextStringValue. If too many synchronization keywords are added to getNextStringValue, will it lead to timeout?

Kneel beg warrior to offer the general train of thought that solves a problem!!

✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈

Solution 1:

1, recommend https://github.com/adyliu/idcenter

2. This can be achieved through the third party Redis.

Solution 1:

1, the occurrence of repeated ID, because dirty read, concurrent time does not add synchronized, such as problems

Java itself is multithreaded, so it is not a wise choice to use it in a single thread. At the same time, if synchronized is used in distributed deployment, concurrency can not be controlled

3. If a timeout occurs when you call this method, it indicates that your concurrency has exceeded the limit that the database can handle

Based on the above analysis, it is suggested to adopt the thread pool scheme, and alipay’s single number is carried out with the thread pool scheme.

Instead of incrementing the database by 1, the database updates hundreds or even thousands of numbers at a time, and then allocates those 1000 numbers in a thread pool, which can handle any large number of concurrent requests without any strain on the database.

✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈ ✈