mysql链接出现: No operations allowed after statement closed.
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql链接出现: No operations allowed after statement closed.相关的知识,希望对你有一定的参考价值。
数据库连接配置文件。。
希望有知道的大神指点一下。。。
有两个方法,
第一种是在DB连接字符串后面加一个参数。
这样的话,如果当前链接因为超时断掉了,那么驱动程序会自动重新连接数据库。
jdbc:mysql://localhost:3306/makhtutat?autoReconnect=true
不过Mysql并不建议使用这个方法。因为第一个DB操作失败的后,第二DB成功前如果出现了重新连接的效果。这个失败操作将不会处于一个事务以内,第二DB操作如果成功的话,这个事务将被提交。
conn.createStatement().execute(
"UPDATE checking_account SET balance = balance - 1000.00 WHERE customer='Smith'");
conn.createStatement().execute(
"UPDATE savings_account SET balance = balance + 1000.00 WHERE customer='Smith'");
conn.commit();
当然如果出现了重新连接,一些用户变量和临时表的信息也会丢失。
另一种方法是Mysql推荐的,需要程序员手动处理异常。
[java] view plaincopyprint?
<span style="font-family:Microsoft YaHei;font-size:12px;">public void doBusinessOp() throws SQLException
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
int retryCount = 5;
boolean transactionCompleted = false;
do
try
conn = getConnection(); // assume getting this from a
// javax.sql.DataSource, or the
// java.sql.DriverManager
conn.setAutoCommit(false);
retryCount = 0;
stmt = conn.createStatement();
String query = "SELECT foo FROM bar ORDER BY baz";
rs = stmt.executeQuery(query);
while (rs.next())
all.close()
transactionCompleted = true;
catch (SQLException sqlEx)
String sqlState = sqlEx.getSQLState();
// 这个08S01就是这个异常的sql状态。单独处理手动重新链接就可以了。
if ("08S01".equals(sqlState) || "40001".equals(sqlState))
retryCount--;
else
retryCount = 0;
finally
all close:
while (!transactionCompleted && (retryCount > 0));
</span> 参考技术A 这个没问题, 能帮忙解决一下的哦
能否看看wo 的网名的啊?帮忙搞定一下啊
com.mysql.cj.exceptions.ConnectionIsClosedException: No operations allowed after connection closed.
目录
一、功能背景
在SpringBoot项目中使用第三方数据库进行业务处理,需手动配置连接信息,手段创建连接进行操作第三方数据库。
二、错误信息
Caused by: com.mysql.cj.exceptions.ConnectionIsClosedException: No operations allowed after connection closed.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
at com.mysql.cj.NativeSession.checkClosed(NativeSession.java:1171)
at com.mysql.cj.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:573)
at com.mysql.cj.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:1595)
... 96 common frames omitted
三、相关代码
public List<Map<String, Object>> getDetailData() throws Exception
String jdbcUrl = "jdbc:mysql://xxxxxxx:3306/demo";
String driverName = "com.mysql.cj.jdbc.Driver";
String username = "";
String password = "";
DBHelper dbHelper = new DBHelper(jdbcUrl, driverName, username, Base64.decodeStr(password));
Connection connection = dbHelper.conn;
if (ObjectUtil.isEmpty(connection))
throw new Exception("数据库连接异常");
String variablesSql = "show variables like 'lower_case_table_names'";
// 预执行加载
PreparedStatement pst = null;
// 结果集
ResultSet resultSet = null;
List<Map<String, Object>> list = new ArrayList<>();
try
pst = connection.prepareStatement(variablesSql);
resultSet = pst.executeQuery();
ResultSetMetaData rsmd = resultSet.getMetaData();
int columnCount = rsmd.getColumnCount();
while (resultSet.next())
Map<String, Object> valueMap = new LinkedHashMap();
for (int i = 1; i <= columnCount; i++)
// 通过序号获取列名,起始值为1
String columnName = rsmd.getColumnLabel(i);
// 通过列名获取值
String columnValue = resultSet.getString(columnName);
valueMap.put(columnName, columnValue);
list.add(valueMap);
catch (Exception e)
log.error("关闭数据库连接,出现异常", e);
throw new Exception("获取表信息,出现异常", e);
finally
try
if (Objects.nonNull(resultSet))
resultSet.close();
if (Objects.nonNull(pst))
pst.close();
if (Objects.nonNull(connection))
connection.close();
catch (Exception e)
log.error("关闭数据库连接,出现异常", e);
return list;
四、问题原因
Mysql服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该connection。这就是问题的所在,在C3P0 pools中的connections如果空闲超过8小时,Mysql将其断开,而C3P0并不知道该connection已经失效,如果这时有Client请求connection,C3P0将该失效的Connection提供给Client,将会造成上面的异常。
四、解决办法
1、修改dbDriver
把spring.datasource.driverClassName修改为:com.mysql.jdbc.Driver
修改后代码为:
public List<Map<String, Object>> getDetailData() throws Exception
String jdbcUrl = "jdbc:mysql://xxxxxxx:3306/demo";
String driverName = "com.mysql.jdbc.Driver";
String username = "";
String password = "";
DBHelper dbHelper = new DBHelper(jdbcUrl, driverName, username, Base64.decodeStr(password));
Connection connection = dbHelper.conn;
if (ObjectUtil.isEmpty(connection))
throw new Exception("数据库连接异常");
String variablesSql = "show variables like 'lower_case_table_names'";
// 预执行加载
PreparedStatement pst = null;
// 结果集
ResultSet resultSet = null;
List<Map<String, Object>> list = new ArrayList<>();
try
pst = connection.prepareStatement(variablesSql);
resultSet = pst.executeQuery();
ResultSetMetaData rsmd = resultSet.getMetaData();
int columnCount = rsmd.getColumnCount();
while (resultSet.next())
Map<String, Object> valueMap = new LinkedHashMap();
for (int i = 1; i <= columnCount; i++)
// 通过序号获取列名,起始值为1
String columnName = rsmd.getColumnLabel(i);
// 通过列名获取值
String columnValue = resultSet.getString(columnName);
valueMap.put(columnName, columnValue);
list.add(valueMap);
catch (Exception e)
log.error("关闭数据库连接,出现异常", e);
throw new Exception("获取表信息,出现异常", e);
finally
try
if (Objects.nonNull(resultSet))
resultSet.close();
if (Objects.nonNull(pst))
pst.close();
if (Objects.nonNull(connection))
connection.close();
catch (Exception e)
log.error("关闭数据库连接,出现异常", e);
return list;
2、修改数据库配置
修改服务端连接超时时间
show global variables like 'wait_timeout';
set global wait_timeout=172800;
3、通过修改配置文件信息
#连接池配置
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=false
spring.datasource.test-while-idle=true
spring.datasource.time-between-eviction-runs-millis=18800
配置datasource时需要配置相应的连接池参数,定是去检查连接的有效性,定时清理无效的连接。配置完重启服务即生效。
注:第三种方案不适用本文章对应的功能,只是一种解决方案。
以上是关于mysql链接出现: No operations allowed after statement closed.的主要内容,如果未能解决你的问题,请参考以下文章
java连接mysql出现异常No operations allowed after connection closed,怎么破?
MySQLNonTransientConnectionException: No operations allowed after statement closed hibernate
mysql数据库连接不定时报错,no operations allowed...
Spring Boot连接MySQL长时间不连接后报错`com.mysql.cj.core.exceptions.ConnectionIsClosedException: No operations
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after co
com.mysql.cj.exceptions.ConnectionIsClosedException: No operations allowed after connection closed.