MySQL数据库连接池泄露导致MySQL Server超时关闭连接
前言
最近做项目,发现老项目出现xxx,这个错误其实很简单,出现在MySQL数据库Server端对长时间没有使用的client连接执行清楚处理,因为是druid数据库,且在github也出现这样的issue:The last packet successfully received from the server was 6,011 milliseconds ago. The last packet sent successfully to the server was 6,011 milliseconds ago.,所以怀疑是不是druid配置的问题,毕竟连接池会定时的检查连接,但是实际排查发现不是那么回事,是连接池泄露了,只不过并发不大,表现为{conn-10002} discard错误而已。
准备
按照笔者上次的文章mybatis plus相同Id与xml配置错误时,mybatis plus解决逻辑_mybatis plus xml文件查询id名字相同-CSDN博客
准备数据库,且通过开启root权限

demo
demo简单写一下,实际项目肯定复杂很多
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.17</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.22</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2.7.17</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency></dependencies>
写一个main controller dao
@SpringBootApplication
@MapperScan("org.example.druid.demo.dao")
public class DruidMain {public static void main(String[] args) {SpringApplication.run(DruidMain.class, args);}
}@RestController
public class DemoController {@Autowiredprivate UserDao userDao;@RequestMapping(value = "/demo", method = RequestMethod.GET)public String demo(){int num = userDao.updateUser();return "{\"update\" : " + num + "}";}
}@Mapper
public interface UserDao {@Update("update User set age = 30 where id = 1")int updateUser();
}
配置文件
spring.datasource.druid.url= jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.druid.username= root
spring.datasource.druid.password= 123456i
spring.datasource.druid.driver-class-name= com.mysql.cj.jdbc.Driver
spring.datasource.druid.initialSize=2
spring.datasource.druid.minIdle=2
spring.datasource.druid.maxActive=2
spring.datasource.druid.maxWait=20000
spring.datasource.druid.timeBetweenEvictionRunsMillis=1000
spring.datasource.druid.minEvictableIdleTimeMillis=30000
spring.datasource.druid.validationQuery=SELECT 1
spring.datasource.druid.validationQueryTimeout=1
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.keepAlive=true
spring.datasource.druid.socketTimeout=6000
spring.datasource.druid.poolPreparedStatements=true
访问 http://localhost:8080/demo

这一步实际上没什么问题,但是如果涉及编程式事务,那么可能出现代码逻辑漏洞
@Configuration
public class DemoConfiguration {@Beanpublic PlatformTransactionManager initPlatformTransactionManager(DruidDataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}@RestController
public class DemoController {@Autowiredprivate UserDao userDao;@Autowiredprivate PlatformTransactionManager transactionManager;@RequestMapping(value = "/demo", method = RequestMethod.GET)public String demo(){TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());int num = 0;try {num = userDao.updateUser();transactionManager.commit(transactionStatus);} catch (TransactionException e) {transactionManager.rollback(transactionStatus);}return "{\"update\" : " + num + "}";}
}
这样写也没问题,但是,如果我们在事务拿到后,因为一些逻辑return呢

设置MySQL的超时时间

通过临时设置或者永久设置,--来自bing AI搜索

比如我们临时设置1分钟试试,问题复现

表现为{conn-10002} discard
2025-02-25 21:52:26.692 DEBUG 2129 --- [nio-8080-exec-1] c.a.druid.pool.PreparedStatementPool : {conn-10002, pstmt-20000} exit cache
2025-02-25 21:52:26.695 DEBUG 2129 --- [nio-8080-exec-1] com.alibaba.druid.util.JdbcUtils : close connection error
排查过程
The last packet successfully received from the server was 6,006 milliseconds ago. The last packet sent successfully to the server was 6,006 milliseconds ago.
2025-02-25 21:52:26.690 ERROR 2129 --- [nio-8080-exec-1] druid.sql.Statement : {conn-10002, pstmt-20002} execute error. select * from Usercom.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 183,457 milliseconds ago. The last packet sent successfully to the server was 183,458 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 com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:175) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:354) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3462) [druid-1.2.22.jar:na]at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:434) [druid-1.2.22.jar:na]at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3460) [druid-1.2.22.jar:na]at com.alibaba.druid.wall.WallFilter.preparedStatement_execute(WallFilter.java:686) [druid-1.2.22.jar:na]at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3460) [druid-1.2.22.jar:na]at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:434) [druid-1.2.22.jar:na]at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3460) [druid-1.2.22.jar:na]at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.execute(PreparedStatementProxyImpl.java:158) [druid-1.2.22.jar:na]at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:483) [druid-1.2.22.jar:na]at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:80) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:65) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:90) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) [mybatis-3.5.14.jar:3.5.14]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_431]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_431]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_431]at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_431]at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) [mybatis-spring-2.1.2.jar:2.1.2]at com.sun.proxy.$Proxy57.selectList(Unknown Source) [na:na]at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224) [mybatis-spring-2.1.2.jar:2.1.2]at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) [mybatis-3.5.14.jar:3.5.14]at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) [mybatis-3.5.14.jar:3.5.14]at com.sun.proxy.$Proxy61.selectUsers(Unknown Source) [na:na]at org.example.druid.demo.controller.DemoController.getUsers(DemoController.java:51) [classes/:na]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_431]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_431]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_431]at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_431]at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) [spring-web-5.3.30.jar:5.3.30]at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) [spring-web-5.3.30.jar:5.3.30]at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) [spring-webmvc-5.3.30.jar:5.3.30]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) [spring-webmvc-5.3.30.jar:5.3.30]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) [spring-webmvc-5.3.30.jar:5.3.30]at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.3.30.jar:5.3.30]at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072) [spring-webmvc-5.3.30.jar:5.3.30]at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965) [spring-webmvc-5.3.30.jar:5.3.30]at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.30.jar:5.3.30]at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.3.30.jar:5.3.30]at javax.servlet.http.HttpServlet.service(HttpServlet.java:529) [tomcat-embed-core-9.0.82.jar:4.0.FR]at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.3.30.jar:5.3.30]at javax.servlet.http.HttpServlet.service(HttpServlet.java:623) [tomcat-embed-core-9.0.82.jar:4.0.FR]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) [tomcat-embed-websocket-9.0.82.jar:9.0.82]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.3.30.jar:5.3.30]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.30.jar:5.3.30]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.3.30.jar:5.3.30]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.30.jar:5.3.30]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.30.jar:5.3.30]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) [spring-web-5.3.30.jar:5.3.30]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1794) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) [tomcat-embed-core-9.0.82.jar:9.0.82]at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.82.jar:9.0.82]at java.lang.Thread.run(Thread.java:750) [na:1.8.0_431]
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: The last packet successfully received from the server was 183,457 milliseconds ago. The last packet sent successfully to the server was 183,458 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.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_431]at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_431]at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_431]at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_431]at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:62) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:150) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:166) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.NativeProtocol.readMessage(NativeProtocol.java:582) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:762) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.NativeProtocol.sendCommand(NativeProtocol.java:701) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.NativeProtocol.sendQueryPacket(NativeProtocol.java:1052) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.NativeSession.execSQL(NativeSession.java:657) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:893) ~[mysql-connector-j-8.0.33.jar:8.0.33]... 83 common frames omitted
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.at com.mysql.cj.protocol.FullReadInputStream.readFully(FullReadInputStream.java:67) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.SimplePacketReader.readHeaderLocal(SimplePacketReader.java:81) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:63) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:45) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:52) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.TimeTrackingPacketReader.readHeader(TimeTrackingPacketReader.java:41) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.MultiPacketReader.readHeader(MultiPacketReader.java:54) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.MultiPacketReader.readHeader(MultiPacketReader.java:44) ~[mysql-connector-j-8.0.33.jar:8.0.33]at com.mysql.cj.protocol.a.NativeProtocol.readMessage(NativeProtocol.java:576) ~[mysql-connector-j-8.0.33.jar:8.0.33]... 88 common frames omitted
这个问题在github也有类似的情况,但是不一定是笔者遇到的问题:https://github.com/alibaba/druid/issues/5963
对于连接泄露可以配置泄露连接强制回收,但是这个仅在排查问题使用
removeAbandoned: true
removeAbandonedTimeoutMillis: 30000 #(以毫秒数为单位)
logAbandoned: true
貌似有用,但是实际情况是占用数据库连接的线程并不一定是问题的代码逻辑,我这里仅仅写了一个controller,刚好对应上

所以排查还需要另外的思路,下面演示解决A的锅B来背的案例。
解决方法
开启连接池连接的状态日志,这里以druid为例
com.alibaba.druid.filter.logging.LogFilter

既然查看连接情况,那么这个最关键
spring.datasource.druid.filters=stat,wall,slf4j
logging.level.com.alibaba.druid=TRACE
#最关键的日志
logging.level.druid.sql.Connection=TRACE
当然笔者使用的MySQL版本8.0,这里是客户端缓存,MySQL8.0已经删除了查询缓存,而且这里是更新操作,毕竟查询缓存命中效率比较低,还是吞吐量比较重要,还增加了查询重写插件
以另一个不是事务的请求为例,用于验证问题

update的连接调用

等待1分钟,并发多次请求查询连接后就会报错

错误日志分析

错误的id为10002,从日志往上追溯

这里就是查询业务背了开始更新业务的锅,毕竟查询没有事务。事务代码BUG导致连接没被连接池回收 ,但被查询业务使用了连接,而且有时候可能和mysql Server的一些超时断掉连接的特性结合,那么问题就复杂了。
找到问题就好处理有问题的代码了,毕竟解决问题很简单,找到问题很难。
总结
我们在写代码时,尽量还是使用框架封装的逻辑,比如连接池,比如Spring声明式事务,可以避免编程式事务在写代码时的逻辑漏洞,因为在没触发的时候很难出现,测试很多时候不充分。实际上一起写jdbc的时候还很少出现这个问题,因为那个时候会非常注意连接的回收,事务的提交逻辑,但是Spring自动管理后,这个就很少注意了,因为注解声明式事务太方便了,只有特殊时候才会自己管理事务。
另外这个问题具备隐蔽性,因为报错是MySQL驱动连接MySQL Server报超时未使用关闭连接,但是此处示例的根源却是编程式事务导致连接池泄露,单个问题实际上可以头痛医头,但是当一些mysqlServer的特性加持下,就变成了头痛医脚的感觉了,解决问题很容易,发现问题很难。
相关文章:
MySQL数据库连接池泄露导致MySQL Server超时关闭连接
前言 最近做项目,发现老项目出现xxx,这个错误其实很简单,出现在MySQL数据库Server端对长时间没有使用的client连接执行清楚处理,因为是druid数据库,且在github也出现这样的issue:The last packet successf…...
力扣 下一个排列
交换位置,双指针,排序。 题目 下一个排列即在组成的排列中的下一个大的数,然后当这个排列为降序时即这个排列最大,因为大的数在前面,降序排列的下一个数即升序。所以,要是想找到当前排列的下一个排列&…...
Fisher散度:从信息几何到机器学习的隐藏利器
Fisher散度:从信息几何到机器学习的隐藏利器 在机器学习和统计学中,比较两个概率分布的差异是常见任务,比如评估真实分布与模型预测分布的差距。KL散度(Kullback-Leibler Divergence)可能是大家熟悉的选择,…...
事务管理-03.事务进阶-propagation属性
一.工具 在介绍事务的propagation属性前,我们首先介绍一个工具:Grep Console,该工具用来实现将idea输出出的日志信息进行选择性的高亮展示。 当要选择日志中的某一部分高亮展示时,只需要右键点击Add Highlight即可。此时日志中所…...
Pretraining Language Models with Text-Attributed Heterogeneous Graphs
Pretraining Language Models with Text-Attributed Heterogeneous Graphs EMNLP 推荐指数:#paper/⭐⭐# 贡献: 我们研究了在更复杂的数据结构上预训练LM的问题,即,TAHG。与大多数只能从每个节点的文本描述中学习的PLM不同&…...
模型疑问图像、嵌入、推理类型与说明
在进行模型使用的时候,有时候会碰到模型存在模型类型需要选择的情况,如下面deepseek模型选择模型类型图像、嵌入、推理。 以下是针对此问题的了解与说明: DeepSeek 模型是一个多模态人工智能模型,能够同时处理图像和文本数据,并在多种任务中实现高效的嵌入表示和推理。以下…...
WiFi IEEE 802.11协议精读:IEEE 802.11-2007,6,MAC service definition MAC服务定义
继续精读IEEE 802.11-2007 6,MAC service definition MAC服务定义 6.1 MAC服务概述 6.1.1 数据服务 此服务为对等逻辑链路控制(LLC)实体提供交换MAC服务数据单元(MSDU)的能力。为支持此服务,本地媒体访…...
Visual Studio Code 跨平台安装与配置指南(附官方下载链接)
一、软件定位与核心功能 Visual Studio Code(简称VS Code)是微软开发的开源跨平台代码编辑器,支持超过50种编程语言的智能补全、调试和版本控制功能。2025版本新增AI辅助编程模块,可自动生成单元测试代码和API文档注释。 二、下载…...
deepseek自动化代码生成
使用流程 效果第一步:注册生成各种大模型的API第二步:注册成功后生成API第三步:下载vscode在vscode中下载agent,这里推荐使用cline 第四步:安装完成后,设置模型信息第一步选择API provider: Ope…...
RK3568开发笔记-AD7616调试笔记
目录 前言 一、AD7616介绍 高分辨率 高速采样速率 宽模拟输入范围 集成丰富功能 二、原理图连接 三、设备树配置 四、内核驱动配置 五、AD芯片测试 总结 前言 在嵌入式数据采集领域,将模拟信号精准转换为数字信号至关重要。AD7616 作为一款性能卓越的 16 位模数转换器…...
【DeepSeek开源:会带来多大的影响】
DeepSeek 开源,震撼登场对云计算行业的冲击 巨头云厂商的新机遇 DeepSeek 开源后,为云计算行业带来了巨大的变革,尤其是为巨头云厂商创造了新的发展机遇。以阿里云为例,它作为云计算行业的领军者,与 DeepSeek 的合作…...
transformer架构嵌入层位置编码之动态NTK-aware位置编码
前文,我们已经构建了一个小型的字符级语言模型,是在transformer架构基础上实现的最基本的模型,我们肯定是希望对该模型进行改进和完善的。所以我们的另外一篇文章也从数据预处理、模型架构、训练策略、评估方法、代码结构、错误处理、性能优化等多个方面提出具体的改进点,但…...
OceanBase + DeepSeek:5分钟免费搭建企业知识库
过去一个月,DeepSeek 在全球范围内引发了热烈讨论。其突破性的 AI 能力使其日流量显著超越 Claude 和 Perplexity,吸引了众多企业和技术专家的高度关注。随着 AI 技术的不断进步,企业正面临一场深刻的智能化变革——如何通过 AI 重构业务&…...
水利工程安全包括哪几个方面
水利工程安全培训的内容主要包括以下几个方面: 基础知识和技能培训 : 法律法规 :学习水利工程相关的安全生产法律法规,了解安全生产标准及规范。 事故案例 :通过分析事故案例,了解事故原因和教训&#x…...
基于 sklearn 的均值偏移聚类算法的应用
基于 sklearn 的均值偏移聚类算法的应用 在机器学习和数据挖掘中,聚类算法是一类非常重要的无监督学习方法。它的目的是将数据集中的数据点划分为若干个类,使得同一类的样本点彼此相似,而不同类的样本点相互之间差异较大。均值偏移聚类&…...
C/C++语言知识点二
1. 编程算法之“哨兵”思想 哨兵思想是一种编程技巧,通过在数据结构的边界或特定位置放置一个特殊值(称为“哨兵”),来简化逻辑判断和提高代码效率。哨兵通常是一个标记值,用于指示某种条件或边界,从而避免…...
国产OS上完整编译Qt5.15、搭建基本开发环境需要的库
近期有师弟问我国产OS安装Qt5.15编译老是不完整,不是没声音,就是没视频,或者没有xcb。通过QEMU模拟Arm64,闲来20几天摸索,完整编译了Qt5.15,并编译成功了我的SDR玩具taskBus。 1.主要结论: 该O…...
Python 编程题第一节:判断素数、求阶乘、求圆的周长和面积、求三角形斜边长、比较三个数的大小、找出区间内的素数
判断素数 挺简单的,设一个flag来判断是否是素数,从2开始到前一个数,可以整除便不是素数,1不是素数 aint(input()) flagFalse for i in range(2,a):if a%i0:flagTruebreak if flagTrue or a1:print("不是素数") else:p…...
Python批量压缩并上载CSV数据文件到Box企业云盘
Python在Windows下批量压缩CSV文件为ZIP并异步上传到Box企业云,需整合文件处理、异步任务、配置管理和日志记录功能。 该方案通过线程池实现异步上传,每个文件独立压缩处理,异常发生时继续后续任务。日志系统记录完整操作流水,配置…...
MyBatis简明教程
MyBatis 是一个用于简化数据库操作的持久层框架,它的核心思想是 将 SQL 与 Java 代码解耦,让开发者专注于 SQL 的编写,同时自动处理重复的数据库操作步骤。 一、核心思想:SQL 与 Java 解耦 传统 JDBC 需要开发者手动管理数据库连…...
有什么区别?Elastic 和 Splunk 数据层
作者:来自 Elastic Ugo Sangiorgi, Matt Wehle 了解 Elastic 和 Splunk 数据管理方法之间的主要区别,以便做出明智的决策,实现高效的数据处理 在数据管理领域,在讨论如何根据不同的性能要求提供和/或保留数据时,经常会…...
Tips :仿真竞争条件 指的是什么?
文章目录 **为什么会出现仿真竞争条件?****典型场景举例****System Verilog 如何解决竞争条件?****1. 使用 `program` 块隔离测试平台****2. 使用 `clocking` 块明确时序关系****3. 非阻塞赋值(`<=`)的合理使用****竞争条件的根本原因****总结****代码结构****1. 设计模…...
BGP状态和机制
BGP邻居优化 为了增加稳定性,通常建议实验回环口来建立邻居。更新源:建立邻居和邻居所学习到的路由的下一跳。多跳:EBGP邻居建立默认选哟直连,因为TTL=1,如果非直连,必须修改TTL。命令备注peer 2.2.2.2 connect-interface lo1配置更新源peer 2.2.2.2 ebgp-max-hop 2配置T…...
【电机控制器】PY32F00BF15U6TR-从KEIL5中计算资源消耗资源
【电机控制器】PY32F00BF15U6TR-从KEIL5中计算资源消耗资源 文章目录 [TOC](文章目录) 前言一、MCU芯片手册二、实验三、实验结论四、参考资料总结 前言 使用工具: 1.KEIL5编译器 提示:以下是本篇文章正文内容,下面案例可供参考 一、MCU芯片…...
CaffeineCache自定义缓存时间
文章目录 1、POM文件依赖2、声明缓存3、缓存使用4、测试缓存5、自定义缓存过期时间6、测试自定义超时时间 1、POM文件依赖 <dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>3.1…...
python实战项目58:采集蜻蜓FM热门音频top排行榜
python实战项目58:采集蜻蜓FM热门音频top排行榜 一、采集流程介绍二、数据接口采集三、使用xpath提取页面数据1、抓包,找到数据接口2、发送请求,获取数据3、提取数据4、保存数据一、采集流程介绍 蜻蜓FM热门音频top排行榜的链接为: https://m.qingting.fm/rank/,首页如下图…...
STM32【3】芯片的底层组成概论
关于单片机的组成 单片机的意思是,小小计算电脑,麻雀虽小,五脏俱全,里面包含了CPU,ROM,RAM,各种外设。 CPU地位最高,可以访问ROM和RAM,Flash,GPIO等外设&…...
基于django图书信息管理系统的搭建(增删改查)
✍django项目搭建教程 ☞ ----------------- 教程 本文主要讲解django如何连接数据库MySQL并且可视化展示,实现增删改查功能 目录 一. 创建django应用 二. 数据库配置 三. 查看数据库 四. 编写代码 4.1视图函数 4.2 配置URL 4.3创建模板文件 4.…...
Kotlin 知识点二 延迟初始化和密封类
对变量延迟初始化 Kotlin 语言的许多特性,包括变量不可变,变量不可为空,等等。这些特性 都是为了尽可能地保证程序安全而设计的,但是有些时候这些特性也会在编码时给我们带来不 少的麻烦。 比如,如果你的类中存在很多…...
基于SpringBoot的“古城景区管理系统”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“古城景区管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统整体功能图 系统首页界面 系统注册界面 景…...
