原因分析

查看了Mysql的文档,以及Connector/J的文档以及在线说明发现,出现这种异常的原因是:

  Mysql服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。这就是问题的所在,在C3P0 pools中的connections如果空闲超过8小时,Mysql将其断开,而C3P0并不知道该connection已经失效,如果这时有Client请求connection,C3P0将该失效的Connection提供给Client,将会造成上面的异常。

nutz配置解决方案:

myapp.properties信息

db-driver=com.mysql.jdbc.Driver
db-url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8
db-username=mytest
db-password=123456

core.js信息

var ioc = {

config : {
type : "org.nutz.ioc.impl.PropertiesProxy",
fields : {
paths : ["/conf/myapp.properties"]
}
},

dataSource : {
type :"com.mchange.v2.c3p0.ComboPooledDataSource",
events : {
depose :"close"
},
fields : {
driverClass : {java :"$config.get('db-driver')"},
jdbcUrl             : {java :"$config.get('db-url')"},
user        : {java :"$config.get('db-username')"},
password        : {java :"$config.get('db-password')"},
minPoolSize     : 5,
initialPoolSize : 10,
maxPoolSize     : 100,
testConnectionOnCheckin : true,
automaticTestTable : "C3P0TestTable",      --    这些是针对MySQLNonTransientConnectionException新加的属性
idleConnectionTestPeriod : 18000,
maxIdleTime : 300,
maxStatements : 0,          --防止c3p0 APPARENT DEADLOCK的问题
numHelperThreads : 5    --防止c3p0 APPARENT DEADLOCK的问题
}
},
// Dao
dao : {
type :'com.test.my.TestDao',
args : [ {refer :"dataSource"}]
}
};

com.test.my.TestDao 类,该类直接继承了NutDao ,如果非必要,那么type里面可以直接写NutDao 。

public class TestDao extends NutDao {

public TestDao () {
super();
// TODO Auto-generated constructor stub
}

public TestDao (DataSource dataSource, SqlManager sqlManager) {
super(dataSource, sqlManager);
// TODO Auto-generated constructor stub
}

public TestDao (DataSource dataSource) {
super(dataSource);
// TODO Auto-generated constructor stub
}

//下面是一些自己的方法
}

解决方案

解决的方法有3种:

  1. 增加 wait_timeout 的时间。
  2. 减少 Connection pools 中 connection 的 lifetime。
  3. 测试 Connection pools 中 connection 的有效性。

当然最好的办法是同时综合使用上述3种方法,下面就 DBCP、C3P0 和 simple jdbc dataSource 分别做一说明,假设 wait_timeout 为默认的8小时

DBCP 增加以下配置信息:


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"

C3P0 增加以下配置信息:


//获取connnection时测试是否有效
testConnectionOnCheckin = true

//自动测试的table名称
automaticTestTable=C3P0TestTable

//set to something much less than wait_timeout, prevents connections from going stale
idleConnectionTestPeriod = 18000

//set to something slightly less than wait_timeout, preventing 'stale' connections from being handed out
maxIdleTime = 25000

//if you can take the performance 'hit', set to "true"
testConnectionOnCheckout = true

simple jdbc dataSource 增加以下配置信息:


Pool.PingQuery = select 1

Pool.PingEnabled = true

Pool.PingConnectionsOlderThan = 0

//对于空闲的连接一个小时检查一次
Pool.PingConnectionsNotUsedFor = 3600000

其他方案(不推荐)

  对于 MySQL5 之前的版本,如 Mysql4.x,只需要修改连接池配置中的 URL,添加一个参数:autoReconnect=true(如jdbc:mysql://hostaddress:3306/schemaname?autoReconnect=true),如果是 MySQL5 及以后的版本,则需要修改 my.cnf(或者my.ini) 文件,在 [mysqld] 后面添加上:

wait_timeout = n
interactive-timeout = n

其中 n 为服务器关闭交互式连接前等待活动的秒数。可是就部署而言每次修改 my.ini 比较麻烦,而且 n 等于多少才是合适的值呢? 所以并不推荐这个解决办法。)

<c3p0-config>
<default-config>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement">3</property>

<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts">30</property>

<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay">1000</property>

<!--连接关闭时默认将所有未提交的操作回滚。Default: false -->
<property name="autoCommitOnClose">false</property>

<!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么
属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试
使用。Default: null-->
<property name="automaticTestTable">Test</property>

<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->
<property name="breakAfterAcquireFailure">false</property>

<!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出
SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->
<property name="checkoutTimeout">100</property>

<!--通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径。
Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->
<property name="connectionTesterClassName"></property>

<!--指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置,默认null即可
Default: null-->
<property name="factoryClassLocation">null</property>

<!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs.
(文档原文)作者强烈建议不使用的一个属性-->
<property name="forceIgnoreUnresolvedTransactions">false</property>

<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod">60</property>

<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize">3</property>

<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime">60</property>

<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize">15</property>

<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->
<property name="maxStatements">100</property>

<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
<property name="maxStatementsPerConnection"></property>

<!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能
通过多线程实现多个操作同时被执行。Default: 3-->
<property name="numHelperThreads">3</property>

<!--当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0
的数据源时。Default: null-->
<property name="overrideDefaultUser">root</property>

<!--与overrideDefaultUser参数对应使用的一个参数。Default: null-->
<property name="overrideDefaultPassword">password</property>

<!--密码。Default: null-->
<property name="password"></property>

<!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:
测试的表必须在初始数据源的时候就存在。Default: null-->
<property name="preferredTestQuery">select id from test where id=1</property>

<!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->
<property name="propertyCycle">300</property>

<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。Default: false -->
<property name="testConnectionOnCheckout">false</property>

<!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->
<property name="testConnectionOnCheckin">true</property>

<!--用户名。Default: null-->
<property name="user">root</property>

<!--早期的c3p0版本对JDBC接口采用动态反射代理。在早期版本用途广泛的情况下这个参数
允许用户恢复到动态反射代理以解决不稳定的故障。最新的非反射代理更快并且已经开始
广泛的被使用,所以这个参数未必有用。现在原先的动态反射与新的非反射代理同时受到
支持,但今后可能的版本可能不支持动态反射代理。Default: false-->
<property name="usesTraditionalReflectiveProxies">false</property>

<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">25</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">0</property>
<user-overrides user="swaldman">
</user-overrides>
</default-config>
<named-config name="dumbTestConfig">
<property name="maxStatements">200</property>
<user-overrides user="poop">
<property name="maxStatements">300</property>
</user-overrides>
</named-config>
</c3p0-config>

参考:

http://www.blogjava.net/Alpha/archive/2009/03/29/262789.html

http://blog.csdn.net/bedweather/article/details/6743951

http://www.cnblogs.com/hemingwang0902/archive/2012/03/15/2397620.html
http://blog.sina.com.cn/s/blog_53b58e7c010197bj.html

MySQLNonTransientConnectionException: No operations allowed after connection closed的更多相关文章

  1. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.

    com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after co ...

  2. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed. 解决

    ERROR - No operations allowed after connection closed. 2011-12-07 11:36:09 - ERROR - query failed or ...

  3. myBatis连接MySQL报异常:No operations allowed after connection closed.Connection was implicitly closed

    网站运行一个晚上,早上来上班,发现报错: ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTra ...

  4. Mysql异常:MySQLNonTransientConnectionException: No operations allowed after statement closed

    Mysql异常:MySQLNonTransientConnectionException: No operations allowed after statement closed MySQLNonT ...

  5. Spring Boot连接MySQL长时间不连接后报错`com.mysql.cj.core.exceptions.ConnectionIsClosedException: No operations allowed after connection closed.`的解决办法

    报错:com.mysql.cj.core.exceptions.ConnectionIsClosedException: No operations allowed after connection ...

  6. spring boot下mybatis遇到No operations allowed after connection closed.

    在配置文件中添加 # for initial,min,maxspring.datasource.initialSize=5spring.datasource.minIdle=5spring.datas ...

  7. No operations allowed after connection closed--转

    https://www.jianshu.com/p/1626d41572f2 Spring boot的单数据源配置比较简单,只需要在application.properties配置相关的jdbc连接的 ...

  8. Spring Boot环境下出现No operations allowed after connection close错误

    一个基于springcloud的微服务项目,详细配置: SpringCloud + SpringMVC+SpringData JPA+ MySql+Postgresql 其中项目配置了多数据源,前期开 ...

  9. Caused by: java.sql.SQLException: Couldn't perform the operation getAutoCommit: You can't perform any operations on this connection. It has been automatically closed by Proxool for some reason (see lo

    系统启动,一段时间不操作,然后在来操作时,报错如下: Caused by: java.sql.SQLException: Couldn't perform the operation getAutoC ...

随机推荐

  1. pandas 基础用法

    pandas 是一个基于 Numpy 构建, 强大的数据分析工具包 主要功能 独特的数据结构 DataFrame, Series 集成时间序列功能 提供丰富的数学运算操作 灵活处理缺失数据 Serie ...

  2. sdut2165 Crack Mathmen (山东省第二届ACM省赛)

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/svitter/article/details/24270265 本文出自:http://blog.c ...

  3. 【转】每天一个linux命令(48):watch命令

    原文网址:http://www.cnblogs.com/peida/archive/2012/12/31/2840241.html watch是一个非常实用的命令,基本所有的Linux发行版都带有这个 ...

  4. Python+VSCode+Git 学习总结

    稍等,先写个脑图... 继续,读完本文,你会学会: 1.如何在VSCode中写Python代码: 2.如何在VSCode中使用Git: 为什么写这篇总结 首先,我假设你是一名Python语言初学者,你 ...

  5. JavaScriptSerializer类 对象序列化为JSON,JSON反序列化为对象 。

    JavaScriptSerializer 类由异步通信层内部使用,用于序列化和反序列化在浏览器和 Web 服务器之间传递的数据.说白了就是能够直接将一个C#对象传送到前台页面成为javascript对 ...

  6. golang中如何判断文件是否有可执行权限

    本文介绍在Go语言如何检查文件的权限.以检查文件可执行权限为例. 在文件系统中,文件的属性使用uint32表示. 例如 -rwxrwxrwx 判断可执行权限,也就是检查文件mode是否有: --x-- ...

  7. linux 信号处理 二 (信号的默认处理)

    今天碰到一个SIGHUP问题,再复习一遍: 有些信号的默认处理方式为“终止+core”,这里的core表示,进程终止时,会在进程的当前工作目录生产一个core文件,该文件是进程终止时的内存快照,以便以 ...

  8. android开发常用组件【持续更新中。。。】

    UI相关 图片 Android-Universal-Image-Loader:com.nostra13.universalimageloader:异步加载.缓存.显示图片 ImageLoader:co ...

  9. 小峰servlet/jsp(6)jstl核心标签库

    一.引入jstl 需要jstl.jar;standard.jar; 二.jstl核心标签库: c:out         内容输出标签; c:set      用来设置4种属性范围值的标签: c:re ...

  10. Kong管理UI -kong-dashboard (附kong封装webservice方法)

    本文仍然是在centos 6.7的环境下进行                 本文转载请注明出处 —— xiaoEight btw如果要正常使用管理UI,前提为kong已经正常run(可参考)起来,此 ...