myBatis连接MySQL报异常:
No operations allowed after connection closed.; nested exception is com.mysq
查看了Mysql的文档,以及Connector/J的文档以及在线说明发现,出现这种异常的原因是:
Mysql服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。这就是问题的所在,在C3P0 pools中的connections如果空闲超过8小时,Mysql将其断开,而C3P0并不知道该connection已经失效,如果这时有Client请求connection,C3P0将该失效的Connection提供给Client,将会造成上面的异常。
解决的方法有3种:
增加 wait_timeout 的时间。
减少 Connection pools 中 connection 的 lifetime。
测试 Connection pools 中 connection 的有效性。
当然最好的办法是同时综合使用上述3种方法,下面就 DBCP、C3P0 和 simple jdbc dataSource 分别做一说明,假设 wait_timeout 为默认的8小时
增加以下配置validationQuery = “select 1”
testWhileIdle = "true"
//some positive integer
timeBetweenEvictionRunsMillis = 3600000
//set to something smaller than 'wait_timeout'
minEvictableIdleTimeMillis = 18000000
//if you don't mind a hit for every getConnection(), set to "true"
testOnBorrow = "true"
===================================
dbcp数据连接池配置
DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要3个包:commons-dbcp.jar,commons-pool.jar,commons-collections.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。
spring中的配置:
[html] view plain copy
在CODE上查看代码片派生到我的代码片
<!-- 配置dbcp数据源 -->
<bean id="remoteDS" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<!-- 使用的JDBC驱动的完整有效的java 类名 -->
<property name="driverClassName" value="${remote.jdbc.driver}" />
<!-- 传递给JDBC驱动的用于建立连接的URL -->
<property name="url" value="${remote.jdbc.url}" />
<!-- 数据库用户名 -->
<property name="username" value="${remote.jdbc.username}" />
<!-- 用户密码 -->
<property name="password" value="${remote.jdbc.password}" />
<!-- 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个. -->
<property name="testOnBorrow" value="${dbcp.testOnBorrow}" />
<!-- 指明是否在归还到池中前进行检验 -->
<property name="testOnReturn" value="${dbcp.testOnReturn}" />
<!-- 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除. -->
<property name="testWhileIdle" value="${dbcp.testWhileIdle}" />
<!-- SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,
则查询必须是一个SQL SELECT并且必须返回至少一行记录 -->
<property name="validationQuery" value="${dbcp.validationQuery}" />
<!-- 连接池创建的连接的默认的auto-commit状态 -->
<property name="defaultAutoCommit" value="${dbcp.defaultAutoCommit}" />
<!-- 最大空闲连接 -->
<property name="maxIdle" value="${dbcp.maxIdle}" />
<!-- 最大连接数量 -->
<property name="maxActive" value="${dbcp.maxActive}" />
<!-- 连接在池中保持空闲而不被空闲连接回收器线程(如果有)回收的最小时间值,单位毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${dbcp.minEvictableIdleTimeMillis}" />
<!-- 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. 如果设置为非正数,则不运行空闲连接回收器线程 -->
<property name="timeBetweenEvictionRunsMillis" value="${dbcp.timeBetweenEvictionRunsMillis}" />
</bean>
一、参数详解
官方文档:http://commons.apache.org/dbcp/configuration.html
参数 描述
username 传递给JDBC驱动的用于建立连接的用户名
password 传递给JDBC驱动的用于建立连接的密码
url 传递给JDBC驱动的用于建立连接的URL
driverClassName 使用的JDBC驱动的完整有效的java 类名
connectionProperties 当建立新连接时被发送给JDBC驱动的连接参数,格式必须是 [propertyName=property;]*
注意:参数user/password将被明确传递,所以不需要包括在这里。
参数 默认值 描述
defaultAutoCommit true 连接池创建的连接的默认的auto-commit状态
defaultReadOnly driver default 连接池创建的连接的默认的read-only状态. 如果没有设置则setReadOnly方法将不会被调用. (某些驱动不支持只读模式,比如:Informix)
defaultTransactionIsolation driver default 连接池创建的连接的默认的TransactionIsolation状态. 下面列表当中的某一个: (参考javadoc)
NONE
READ_COMMITTED
READ_UNCOMMITTED
REPEATABLE_READ
SERIALIZABLE
defaultCatalog 连接池创建的连接的默认的catalog
参数 默认值 描述
initialSize 0 初始化连接:连接池启动时创建的初始化连接数量,1.2版本后支持
maxActive 8 最大活动连接:连接池在同一时间能够分配的最大活动连接的数量, 如果设置为非正数则表示不限制
maxIdle 8 最大空闲连接:连接池中容许保持空闲状态的最大连接数量,超过的空闲连接将被释放,如果设置为负数表示不限制
minIdle 0 最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,如果设置为0则不创建
maxWait 无限 最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间(以毫秒计数),超过时间则抛出异常,如果设置为-1表示无限等待
参数 默认值 描述
validationQuery SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定,则查询必须是一个SQL SELECT并且必须返回至少一行记录
testOnBorrow true 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
testOnReturn false 指明是否在归还到池中前进行检验
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
testWhileIdle false 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串
timeBetweenEvictionRunsMillis -1 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. 如果设置为非正数,则不运行空闲连接回收器线程
numTestsPerEvictionRun 3 在每次空闲连接回收器线程(如果有)运行时检查的连接数量
minEvictableIdleTimeMillis 1000 * 60 * 30 连接在池中保持空闲而不被空闲连接回收器线程(如果有)回收的最小时间值,单位毫秒
参数 默认值 描述
poolPreparedStatements false 开启池的prepared statement 池功能
maxOpenPreparedStatements 不限制 statement池能够同时分配的打开的statements的最大数量, 如果设置为0表示不限制
这里可以开启PreparedStatements池. 当开启时, 将为每个连接创建一个statement池,并且被下面方法创建的PreparedStatements将被缓存起来:
* public PreparedStatement prepareStatement(String sql)
* public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
注意: 确认连接还有剩余资源可以留给其他statement
参数 默认值 描述
accessToUnderlyingConnectionAllowed false 控制PoolGuard是否容许获取底层连接
如果容许则可以使用下面的方式来获取底层连接:
Connection conn = ds.getConnection();
Connection dconn = ((DelegatingConnection) conn).getInnermostDelegate();
…
conn.close();
默认false不开启, 这是一个有潜在危险的功能, 不适当的编码会造成伤害.(关闭底层连接或者在守护连接已经关闭的情况下继续使用它).请谨慎使用,并且仅当需要直接访问驱动的特定功能时使用.
注意: 不要关闭底层连接, 只能关闭前面的那个.
参数 默认值 描述
removeAbandoned false 标记是否删除泄露的连接,如果他们超过了 removeAbandonedTimout的限制.如果设置为true, 连接被认为是被泄露并且可以被删除,如果空闲时间超过removeAbandonedTimeout. 设置为true可以为写法糟糕的没有关闭连接的程序修复数据库连接.
removeAbandonedTimeout 300 泄露的连接可以被删除的超时值, 单位秒
logAbandoned false 标记当Statement或连接被泄露时是否打印程序的stack traces日志。被泄露的Statements和连接的日志添加在每个连接打开或者生成新的Statement,因为需要生成stack trace。
如果开启”removeAbandoned”,那么连接在被认为泄露时可能被池回收. 这个机制在(getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)时被触发.
举 例当maxActive=20, 活动连接为18,空闲连接为1时可以触发”removeAbandoned”.但是活动连接只有在没有被使用的时间超 过”removeAbandonedTimeout”时才被删除,默认300秒.在resultset中游历不被计算为被使用.
L2-007 家庭房产 (25 分)给定每个人的家庭成员和其自己名下的房产,请你统计出每个家庭的人口数、人均房产面积及房产套数。输入格式:输入第一行给出一个正整数N(≤1000),随后N行,每行按下列格式给出一个人的房产:编号 父 母 k 孩子1 ... 孩子k 房产套数 总面积其中编号是每个人独有的一个4位数的...
名称glGetVertexAttrib - 返回通用顶点属性参数C规范void glGetVertexAttribfv( GLuint index, GLenum pname, GLfloat *params);void glGetVertexAttribiv( GLuint index, GLenum pname, GLint *...
微信小程序设置 background-img 报错微信小程序设置背景图片是会报错 提示必须使用网络资源或者 base64解决办法1 把图片转换为base64格式 (base64图片转换)把右边生成的base64编码放到url中就可以...
cardinality反应了series的维度,即不同的series的数量。序列基数是影响内存(RAM)使用量的主要因素。
序列密码加密代码:解密代码:输入一串字符串,利用产生的随机序列对字符串的每个字符逐个逐比特异或,产生的数,ASCII值变为对应的字符。加密代码:package com.jingfei.Encryptoin.com.jingfei.xulie;import java.math.BigInteger;import java.util.Scanner;public class XuLie...
一路跟踪源码,关键就是这两句:int QDialog::exec(){ Q_D(QDialog); if (d-&gt;eventLoop) { qWarning("QDialog::exec: Recursive call detected"); return -1; } bool deleteOnClose = tes...
高性能爬虫相关(IO多路复用,异步非阻塞)说到提高性能,我们可以想到的是利用多进程、多线程以及单线程实现并发,由于爬虫爬取信息时IO操作较多,所以利用单线程实现并发是较好的选择爬虫本质上还是建立socket连接,通过http请求获取数据本质: sk = socket() # 阻塞 sk.connect(('www.cnblogs.co...
文件后缀对应文件类型表 private static IDictionary<string, string> _mappings = new Dictionary<string, string> (StringComparer.InvariantCultureIgnore...
1. RedisTemplate快速开发 2. 两种实例的redis数据序列化区别 3. 用RedisTemplate还是StringRedisTemplate 4. 总结 1. RedisTemplate快速开发spring-redis对redis的五种数据类型是支持的。这个几个数据操作对象在demo的RedisConfig类中配置了,具体可前去查看代码。本文最重要的点是Object的序列化,下文会着重分析。 HashOperations:对hash类型的数..
vue开发百度地图很不兼容,如果直接循环添加事件会覆盖前面的事件,现采用网上说的一种闭包方式for(var i =0;i<_this.pointArray.length;i++){ var marker1 = new BMap.Marker(new BMap.Point(_this.pointArray[i].lng,_this.pointArray[i].lat)); marker1.setLabel(new BMap.
Android每新建一个项目,都会有两个build.gradle文件,有一个在最外层目录下,有一个在app目录下,如果切换到 Android 模式下则全部在 Gradle Scripts下。下面先介绍看起来少的(最外层目录下的)。主要介绍:jcenter():一个代码仓库,许多的Android开源项目都会将代码托管到jcenter上。作用:配置后,可以在项目中轻松使用任何的jcenter上...
Jsp一共包含三个编译指令和七个动作指令。三个编译指令为:page、include、taglib。七个动作指令为:jsp:forward、jsp:param、jsp:include、jsp:plugin、jsp:useBean、jsp:setProperty、jsp:getProperty。...