文档章节

Mybatis破MySql8小时断线问题

xpbug
 xpbug
发布于 2014/10/08 16:43
字数 971
阅读 12323
收藏 21

MySql有一个系统变量,如图:

以上数值,单位为秒。

mysql的连接允许的闲置时间。当超过闲置时间以后,database端就会将此连接单方面废弃。这时如果使用jdbc继续使用之前的连接,则会收到以下异常:

### Cause: java.sql.SQLException: Could not retrieve transation read-only status server
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:26)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:111)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102)
	at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:119)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
	at com.sun.proxy.$Proxy8.getMonthlyChart(Unknown Source)
	at com.lux.rcc.kpi.bo.ChartABo.getMonthlyChart(ChartABo.java:46)
	at com.lux.rcc.kpi.servlets.ChatAServlet.doGet(ChatAServlet.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:722)
Caused by: java.sql.SQLException: Could not retrieve transation read-only status server
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1086)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:975)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:920)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:951)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:941)
	at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3972)
	at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3943)
	at com.mysql.jdbc.PreparedStatement.checkReadOnlySafeStatement(PreparedStatement.java:1258)
	at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1278)
	at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:62)
	at com.sun.proxy.$Proxy10.execute(Unknown Source)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:59)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:73)
	at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:60)
	at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:267)
	at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:137)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:96)
	at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:77)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:108)
	... 28 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 85,659,759 milliseconds ago.  The last packet sent successfully to the server was 85,659,775 milliseconds ago. 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 property 'autoReconnect=true' to avoid this problem.
	at sun.reflect.GeneratedConstructorAccessor24.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
	at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1129)
	at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3988)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2598)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2828)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2777)
	at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1651)
	at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3966)
	... 44 more
Caused by: java.net.SocketException: Software caused connection abort: socket write error
	at java.net.SocketOutputStream.socketWrite0(Native Method)
	at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
	at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
	at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
	at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
	at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3969)
	... 50 more

mysql允许设置闲置时间,默认是8小时,最大是1年。

大部分客户端都使用连接池以提高性能,如果用户访问量不大,连接池中的连接可能闲置时间超过数据库允许时间,数据库单方面断掉连接,而客户端却不知情。当下一个用户访问时,使用连接池中的连接,则会抛出上述异常。

解决方法可以是增大闲置时间。但这不是一个好方法。闲置时间是有上限的,在极端情况下,还是可能发生异常。此外,长时间保留闲置的连接,会降低数据库性能,消耗内存,最终耗尽数据库的连接数。所以不推荐增大闲置时间。

一般常用的解决方法是在使用一个长时间闲置的连接之前,对它ping一下,确保它还在正常工作。在mybatis自带连接池配置中,是这样做的:

        <environment id="development">
            <transactionManager type="jdbc" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/kpi?autoReconnect=true" />
                <property name="username" value="mysql" />
                <property name="password" value="mysql" />
                <property name="poolPingEnabled" value="true"/>
                <property name="poolPingQuery" value="select now() from kpi.lastupdatedlog limit 1"/>
                <property name="poolPingConnectionsNotUsedFor" value="3600000"/>
            </dataSource>
        </environment>

配置连接池时,需要声明三个属性:

  1. poolPingEnabled - 默认值是false,当值为true的时候,将开启ping机制。

  2. poolPingQuery - 对数据库进行ping时所使用的sql。

  3. poolPingConnectionsNotUsedFor - 默认值是0,单位是毫秒。我们不能在每次使用连接池之前,都使用ping机制,这会使每一条sql的执行,都要额外执行一次ping语句。所以使用此属性来避免这种不合理做法。我们只针对闲置时间超过某个时间的连接,进行ping。本例中的值为1小时,当从连接池中拿出的连接闲置超过1小时,才会对它进行ping。

© 著作权归作者所有

xpbug
粉丝 304
博文 101
码字总数 124566
作品 0
浦东
程序员
私信 提问
加载中

评论(3)

王静0716
王静0716

引用来自“王静0716”的评论

ping是确保是不是连的上mysql? 为什么不用validationQuery
好像是mybatis原生连接池 与 DruidDataSource的区别
王静0716
王静0716
ping是确保是不是连的上mysql? 为什么不用validationQuery
徐建兴
徐建兴
那如果ping不通该咋办呢??mybatis该如何处理ping不通的数据库连接呢?
Mysql8小时断线,请问如何解决?Druid

@wenshao 你好,想跟你请教个问题: 在实际生产环境中,发现有很多的 java.sql.SQLException: Could not retrieve transation read-only status server Query: insert into的错误日志, 具体...

ivan1114
2014/10/18
5.6K
6
Mysql8小时断线,请问如何解决?

黄大侠: 用你的Framework中,在实际生产环境中,发现有很多的 java.sql.SQLException: Could not retrieve transation read-only status server Query: insert into的错误日志, 具体是在M...

ivan1114
2014/10/18
2K
6
项目用mysql运行一段时间就连接不上了

项目运行一段时间就报不能连接到数据库,网上说是mysql8小时问题,我用的DBCP,已经按照说明加上参数了,但是还是不行,是不是我的配置参数有问题啊?

小99
2014/08/08
1K
2
Mysql8 安装过程及安装过程系列问题记录

前言: 今天,想装个高版本一点的mysql试试,于是下载了一个mysql8的zip版本。 地址:https://dev.mysql.com/downloads/file/?id=484900 没想到安装的过程,竟然卡了半个下午和半个晚上,才走...

路过秋天
03/10
0
0
hiberate c3p0 classNotFound错误

这个奇怪的问题困扰我两天了 再来看看我的hibernate配置文件 其实最开始的时候,connection.provider_class是这样的,但是马上就报了C3P0ConnectionProvider类找不到的错误。 后来我才改成刚...

蓝血的阿健
2015/11/03
387
1

没有更多内容

加载失败,请刷新页面

加载更多

cesium调用天地图服务

本文转载于:专业的前端网站➧cesium调用天地图服务 全球矢量地图服务 var viewer = new Cesium.Viewer("cesiumContainer", { animation: false, //是否显示动画控件 baseLayerPi...

前端老手
22分钟前
4
0
Docker常用命令

场景一:镜像下载、运行及删除 COMMAND DESC 查看 docker images 列出所有镜像(images) docker ps 列出正在运行的容器(containers) docker ps -a 列出所有的容器 docker pull centos 下载cen...

_Change_
23分钟前
4
0
Spark ML使用DataFrame进行K-Means

1.前言 前一篇文章使用了RDD的方式,进行了K-Means聚类. 从Spark 2.0开始,程序包中基于RDD的API spark.mllib已进入维护模式.现在,用于Spark的主要机器学习API是软件包中基于DataFrame的API...

一位不知名的帅气网友
25分钟前
4
0
当遇到美女面试官之如何理解Redis的Expire Key(过期键)

  在面试中遇到美女面试官时,我们以为面试会比较容易过,也能好好表现自己技术的时候了。然而却出现以下这一幕,当美女面试官听说你使用过Redis时,那么问题来了。 👩面试官:Q1,你知道...

ccww_
30分钟前
5
0
干货来袭!游戏背景音乐的角色创建和主界面

角色创建/选择 在一些大型的游戏中,例如多人在线的游戏玩家必须创建一个游戏的虚拟人物进行扮演游戏。初次玩这款游戏的人都会进行创建,选择职业起名字性别选择编辑人设样式等等的操作,通常...

奇亿音乐
33分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部