When using the Mysql database, the most troublesome problem is that the connection error Exception may occur from time to time. Similar exceptions are as follows (Hibernate is used as an example ):
org.hibernate.util.JDBCExceptionReporter - SQL Error:0, SQLState: 08S01org.hibernate.util.JDBCExceptionReporter - The last packet successfully received from the server was43200 milliseconds ago.The last packet sent successfully to the server was 43200 milliseconds ago, which is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection 'autoReconnect=true' to avoid this problem.org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with sessionorg.hibernate.exception.JDBCConnectionException: Could not execute JDBC batch updatecom.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.org.hibernate.util.JDBCExceptionReporter - SQL Error:0, SQLState: 08003org.hibernate.util.JDBCExceptionReporter - No operations allowed after connection closed. Connection was implicitly closed due to underlying exception/error:** BEGIN NESTED EXCEPTION **com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
Most people will be confused about this problem. I have also encountered this problem. After careful research, I found the underlying cause.
I. Cause
In the Mysql configuration, there is a parameter named "wait_timeout", which roughly means that after a client connects to the MySQL database, if the client does not disconnect itself, no operation is performed. The MySQL database will keep the connection "wait_timeout" for such a long time (unit: s, default value: 28800 s, that is, 8 hours). After this time, to save resources, the MySQL database will disconnect the connection from the database. Of course, if the client has any operations on the connection during this "wait_timeout" process, mySQL Databases start to calculate the time again.
In this case, the connection Exception occurs because the connection between our program and MySQL database exceeds the "wait_timeout" time, And the Mysql server disconnects it, however, our program did not make any judgment when using this connection again, so it went down.
So how can we solve this problem?
Ii. Solution
1. Extend the value of wait_timeout in Mysql configuration.
I think some people extend it to a year, and some people say that this value is the maximum value of 21 days, even if the value is set to a larger value, mySQL only recognizes MySQL for 21 days (I did not go to the MySQL document to check it ). However, this is a temporary solution. Even if it can be used for one year, it will still take 7x24 hours for the server to be online.
2. perform the "check" check Mechanism (that is, check whether the connection is valid) Before performing database operations)
There are actually a variety of solutions, Hibernate itself has a configuration method, each connection pool (c3p0, etc.) also has a configuration method, here we take the Hibernate configuration of c3p0 as an example.
<Session-factory> <property name = "hibernate. dialect "> org. hibernate. dialect. mySQL5InnoDBDialect </property> <property name = "hibernate. connection. driver_class "> com. mysql. jdbc. driver </property> <property name = "hibernate. connection. useUnicode "> true </property> <property name =" hibernate. connection. characterEncoding "> UTF-8 </property> <property name =" hibernate. show_ SQL "> true </property> <! -- C3p0 is self-contained in the Hibernate version we use. You do not need to download it. --> <property name = "hibernate. connection. provider_class "> org. hibernate. connection. c3P0ConnectionProvider </property> <property name = "hibernate. c3p0. min_size "> 5 </property> <property name =" hibernate. c3p0. max_size "> 20 </property> <property name =" hibernate. c3p0. timeout "> 1800 </property> <property name =" hibernate. c3p0. max_statements "> 50 </property> <! -- The following sentence is very important and will be explained later --> <property name = "hibernate. c3p0. testConnectionOnCheckout"> true </property> <! -- The following is all mapping, omitted --> </session-factory>
The most important attribute in the above configuration is hibernate. c3p0. testconnectioncheckout, which ensures that the connection is closed every time we pull the connection. However, this attribute may cause some performance loss, and other methods can be used.
There are actually many ways to implement the "check" mechanism. If you are interested, you can learn more about it. C3p0 can also use select 1 and other methods without testconnectioncheckout.