vlambda博客
学习文章列表

MySQL禁用自动连接学习--MySql

如果mysql客户程序发送查询时断开与服务器的连接,它立即并自动尝试重新连接服务器并再次发送查询。然而,即使mysql重新连接成功,你的第1个连接也已经结束,并且以前的会话对象和设定值被丢失:包括临时表、自动提交模式,以及用户和会话变量。该行为很危险,如下面的例子所示,服务器将在你不知道的情况下关闭并重启:


mysql> SET @a=1;
Query OK, 0 rows affected (0.05 sec)
 
mysql> INSERT INTO t VALUES(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: test

Query OK, 1 row affected (1.30 sec)



 
mysql> SELECT * FROM t;
+------+
| a    |
+------+
| NULL |
+------+
1 row in set (0.05 sec)

@a用户变量已经随连接丢失,并且重新连接后它也没有定义。如果有必要在连接断开时终止mysql并提示错误,你可以用--skip-reconnect选项启动mysql客户程序。


实例:

页面报错:


    项目上线之后每天都会报错,每次都要tomcat重启才行。


    HTTP Status 500 - org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: JDBC rollback failed


    org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.TransactionException: JDBC rollback failed

   org.hibernate.TransactionException: JDBC rollback failed

org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:204)

   com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.


分析原因:


之所以会出现这个异常,是因为Mysql在5以后针对超长时间DB连接做了一个处理,那就是如果一个DB连接在无任何操作情况下过了8个小时后,Mysql会自动把这个连接关闭。所以使用连接池的时候虽然连接对象还在但是链接数据库的!




解决的方法有3种: 


增加wait_timeout的时间。 


减少Connection pools中connection的lifetime。 


测试Connection pools中connection的有效性。

我选择了wait_timeout修改成10年,它的单位是秒;个人觉得并没有大问题,因为只是告诉数据库不要处理长连接了。