Java Web concurrency: for update practices, monitoring and solving ., Javawebupdate

Source: Internet
Author: User

Java Web concurrency: for update practices, monitoring and solving ., Javawebupdate

Writer: BYSocket)

Weibo: BYSocket

Douban: BYSocket

 

I. Preface

We have been talking about concurrency. At present, there are two common practices: Lock Mechanism: 1. pessimistic lock; 2. Optimistic lock.

However, this article is mainly used to record my processing experience. In addition, I hope to see the great gods, Daniel, technician, senior student, elder brother, you can post your views and solutions in comments.

 

2. The story is like this.

A table is currently called wallet. The three fields are the amount. The initial value is 0, as shown in:

 

Then we wrote an extremely simple Controller and wrote the following Service code:

?
123456789101112131415 @Override    public void testLock(int lockId)    {        Wallet wallet = walletMapper.selectByPrimaryKey(4);                 BigDecimal one = new BigDecimal(1.00);        BigDecimal two = new BigDecimal(2.00);        BigDecimal three = new BigDecimal(3.00);                 wallet.setWalletAmount(wallet.getWalletAmount().add(one));        wallet.setWalletAvailableAmount(wallet.getWalletAvailableAmount().subtract(two));        wallet.setOldAmount(wallet.getOldAmount().add(three));                      walletMapper.updateByPrimaryKeySelective(wallet);    }

Simply read an object through the primary key. Note that this object is not locked. That is to say, the corresponding SQL is as follows:

?
1234 SELECT    <includerefid="Base_Column_List"/>    FROM wallet    WHERE wallet_id = #{walletId,jdbcType=INTEGER}

I am using MyBiatis. you should understand it. Then, increase 1, decrease 2, and increase 3.

 

Iii. Test is like this

I used the Web application stress testing tool Boom. HTTP (S) load generator compiled by https://github.com/rakyll/boom Go, an alternative to ApacheBench (AB. Boom is a micro program that can perform load tests on Web applications. It is similar to Apache connector, but it has better availability on different platforms and is easy to install and use.

The simple usage is as follows:

?
123456789101112131415161718 boom -n 1000 -c 200 http://www.baidu.com Options:  -n  Number of requests to run.  -c  Number of requests to run concurrently. Total number of requests cannot      be smaller than the concurency level.  -q  Rate limit, in seconds (QPS).  -o  Output type. If none provided, a summary is printed.      "csv" is the only supported alternative. Dumps the response      metrics in comma-seperated values format.    -m  HTTP method, one of GET, POST, PUT, DELETE, HEAD, OPTIONS.  -h  Custom HTTP headers, name1:value1;name2:value2.  -d  HTTP request body.  -T  Content-type, defaults to "text/html".  -a  Basic authentication, username:password.    -allow-insecure Allow bad/expired TLS/SSL certificates.

So I conducted a stress test. It is obvious that this small tool is quite beautiful. Here I have 1000 connections and 100 concurrent connections:

The background program reports an error. What are the errors?

?
1 Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

The original concurrency caused the update dead table. It must be wrong to ignore reading the database data.

 

Iv. Use of FOR UPDATE

First, complete the knowledge: You can use select * for update to lock tables or rows. The pressure on the natural lock table is much greater than that on the lock row. So we adopt the lock row. When will the table be locked?

Assume that there is a form products, which contains two columns: id and name. id is the primary key.
Example 1: (specify the primary key and use this document, row lock)
SELECT * FROM wallet WHERE id = '3' for update;
Example 2: (specify a primary key. If no data is found, no lock is required)
SELECT * FROM wallet WHERE id = '-1' for update;
Example 2: (no primary key, table lock)
SELECT * FROM wallet WHERE name = 'mouse 'for update;
Example 3: (the primary key is not clear, table lock)
SELECT * FROM wallet WHERE id <> '3' for update;
Example 4: (the primary key is not clear, table lock)
SELECT * FROM wallet WHERE id LIKE '3' for update;

 

Therefore, we have updated the Service er method of the Service layer:

?
123456789101112131415 @Override    public void testLock(int lockId)    {        Wallet wallet = walletMapper.selectForUpdate(4);                 BigDecimal one = new BigDecimal(1.00);        BigDecimal two = new BigDecimal(2.00);        BigDecimal three = new BigDecimal(3.00);                 wallet.setWalletAmount(wallet.getWalletAmount().add(one));        wallet.setWalletAvailableAmount(wallet.getWalletAvailableAmount().subtract(two));        wallet.setOldAmount(wallet.getOldAmount().add(three));                      walletMapper.updateByPrimaryKeySelective(wallet);    }

The corresponding SQL statement is as follows:

?
1234567 <selectid="selectForUpdate"resultMap="BaseResultMap"parameterType="java.lang.Integer">  SELECT  <includerefid="Base_Column_List"/>  FROM wallet  WHERE wallet_id = #{walletId,jdbcType=INTEGER}  FOR UPDATE</select>

Naturally, we can see that the lock is applied to the primary key to lock the row.

 

According to the test connection count 1000 and concurrency 100, no error is reported on the console.

The database results are also very good.

 

5. Increasing Pressure

According to the test connection count of 5000 and the concurrency count of 350, no error is reported on the console.

Database results are very wrong !!!

Many values are updated less. Why?

 

6. Check the jvisualvm tool and find that the Tomcat thread connections are insufficient by default.

Then I used the jvisualvm tool for detection. After several tests, we found that the number of connections was 5000, the number of concurrent connections was 350, and the number of concurrent connections increased. The value of a graph remains unchanged.

It is found that the daemon thread of tomcat has been around 200 in the figure. Later, I found tomcat's server. xml and used the default value, which is about 200.

 

Therefore, the configuration is as follows:

1st Methods: Configure Connector
MaxThreads: the maximum number of threads that tomcat can use to process requests.
MinSpareThreads: the initial number of tomcat threads, that is, the minimum number of Idle threads.
MaxSpareThreads: the maximum number of Idle threads in tomcat. If it is exceeded, it will be disabled.
AcceptCount: when the number of threads that can be used to process requests is used, the number of requests that can be placed in the processing queue will not be processed.

?
1 <Connectorport="8080"maxHttpHeaderSize="8192"maxThreads="150"minSpareThreads="25"maxSpareThreads="75"enableLookups="false"redirectPort="8443"acceptCount="100"connectionTimeout="20000"disableUploadTimeout="true"/>

 

2nd Methods: Configure Executor and Connector

Name: name of the thread pool
Class: The class Name of the thread pool.
NamePrefix: The name prefix of the thread in the thread pool.
MaxThreads: Maximum number of threads in the thread pool
MinSpareThreads: Minimum number of Idle threads in the thread pool
MaxIdleTime: when the minimum number of Idle threads is exceeded, multiple threads will wait for this length of time, and then close
ThreadPriority: thread priority

?
123 <Executorname="tomcatThreadPool"namePrefix="req-exec-"maxThreads="1000"minSpareThreads="50"maxIdleTime="60000"/> <Connectorport="8080"protocol="HTTP/1.1"executor="tomcatThreadPool"/>

 

MaxThreads: the maximum number of threads in the thread pool. You can directly configure it to 1000 and then test it with 10000 connections and 800 concurrent connections. See the following figure for ease:

VII. Summary

Thank you for helping me. I hope you will discuss it here. John is grateful.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.