com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications l
前言:一样平常这个报错大多是网络缘故原由导致的,确保你不是网络问题再往下看
问题
在一个方法上(该方法非常复杂执行时间长)加了 @Transactional(rollbackFor = Exception.class)后出现了如下图所示的错误
https://i-blog.csdnimg.cn/direct/86e4d8c3e524463793d53707753f4ffb.png
解决:
经过排查并非网络问题。复现时,在数据库执行show processlist;发现出现了很多存在时间非常长的锁(非死锁),那么大概率是因为数据库毗连池的毗连数不敷导致的数据库毗连失败中断。在长事件中每次举行数据库利用都要占用毗连数,并且因为事件没有提交的缘故原由,不绝没有释放毗连。细化事件的范围即可(不保证整个过程一致)
好比你的主方法在A类,调用了B类的方法,就别在A类方法上加事件注解,而是在B类被调用的上方法加。假如A类调用B类方法是多次调用的话(好比循环),那么他会在B类开启你循环次数个事件,每个事件独立。比方你调用了100次,前99次全乐成,末了一次失败,他是不会回滚前99次的利用的,而是会回滚你第100次的利用。
扩展表明:
@Override
public void B() {
// 操作数据库的方法
}
@Transactional(rollbackFor = Exception.class)
public void A(List<String> strs) {
for (String s: strs) {
B();
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void B() {
// 操作数据库的方法
}
public void A(List<String> strs) {
for (String s: strs) {
B();
}
}
第一段代码中只会启动一个事件,在循环的数据库利用还未全部完成之前(事件未提交)会不绝占用毗连池,第二段代码中,会启动strs聚集巨细个事件,遍历完一个元素便提交一次事件。假如两个方法都加注解,子方法启动事件的时间会判断上一层有没有事件,假如有那么会加入到上一层事件管理,而不是自己启一个事件 。这就涉及到事件的传播特性了
2024.1.04增补
在调试一个复杂的导出时,又出现了Communications link failure的错误,第一反应就是sql执行时间太长超过了druid设置的maxwait(获取毗连期待超时时间)。
分析sql,执行 explain 你的sql 。id为执行优先级,数值一样则从上到下执行。其他参数我就不表明白,网上都有(搜索explain各个参数的意义),主要看table(表别名)、type(扫描类型,不要看到all就觉得很影响性能,其实表小的话不走索引反而更快)、row(预估扫描条数,假如数量很大,那你的sql就必要优化了)、extra(一样平常是看排序请客,尽量让Using index出现多点)。
假如条件答应,我建议把所有毗连条件中的字段(一样平常是id为主)和order by 、 group by后面的字段都加索引
https://i-blog.csdnimg.cn/direct/f4b7382024e74e098ee7e5d4c7047dad.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]