org.apache.ibatis.exceptions.PersistenceException

具体日志如下:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

这里说无法获取JDBC Connection,然后mysql驱动无法接收到mysql服务器的任何数据包。
从其他日志可以看出是能够执行sql语句的,说明是有的JDBC连接有问题,有的JDBC连接没问题。
极大可能是连接池里面的连接过期了,即连接池配置的连接有效期大于了mysql的连接有效期

连接无效解决

首先我是是用的hikari作为mysql数据库连接池
配置如下:

   hikari:
        # 连接池中连接的最长寿命(单位为毫秒)。
        max-lifetime: 270000
        # 连接池能达到的最大规模,包含空闲连接的数量和使用中的连接数量。
        maximum-pool-size: 50
        # 连接超时(单位毫秒)
        connection-timeout: 30000
        # HikariCP试图在连接池里维持的最小空闲连接数。
        minimum-idle: 2
        # 更新操作是否自动提交
        auto-commit: true
        # 连接池中的连接能保持闲置状态的最长时间,单位为毫秒。(默认值: 10 分钟)
        idle-timeout: 240000
        # 是否要隔离内部请求。(默认值: false 。)
        isolate-internal-queries: false

max-lifetime: 270秒
然后数据库配置是

> show global VARIABLES like '%timeout%'
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 60       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 3600     |
| wait_timeout                | 300      |
+-----------------------------+----------+

注意要用 show global VARIABLES不要用show VARIABLES,参考链接[3]

可以看到此处wait_timeout 300秒 是大于270秒的。完全没问题。

那么就要思考hikari的配置是否用上了?

后来发现在代码中配置连接池 bean的问题:

HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setJdbcUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;

此处缺失了Hikari等配置
dataSource.setMaxLifetime();
那么他会走默认的hikari配置

public class HikariDataSource extends HikariConfig implements DataSource, Closeable

去 HikariConfig 中去看发现
private static final long MAX_LIFETIME = MINUTES.toMillis(30);
默认是30分钟,所以会有上面的错误日志出现 连接无效

参考链接:
[1] https://blog.csdn.net/long690276759/article/details/82259550?utm_source=blogxgwz2
[2] https://www.cnblogs.com/ivictor/p/5979731.html
[3] https://www.cnblogs.com/jiunadianshi/articles/2388871.html

你可能感兴趣的:(java)