前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring编程式事务处理不当引起的连接泄露事件

Spring编程式事务处理不当引起的连接泄露事件

作者头像
企鹅号小编
发布2018-01-16 09:40:18
1.6K0
发布2018-01-16 09:40:18
举报
文章被收录于专栏:企鹅号快讯企鹅号快讯

某一日正在孜孜不倦的研究代码,忽然测试童鞋说系统服务挂了,完全不可用。

程序大量抛出如下异常:

对于程序员来说,系统宕机就是军令,更可况是难得一见的连接池泄露问题。因为在企业级的Java项目中,一般采用连接池技术和Spring的事务管理技术来处理数据访问需求,而这两项技术都是久经考验的成熟可靠技术,出问题的几率很小。

其实从异常堆栈来看,明确指出连接池中的连接全部处于激活使用的状态

按照我个人经验来说,连接耗尽可能有两种原因:

1. 系统负载很高,总连接数确实不够用,因此资源耗尽。

2. 数据库连接出现泄漏,无法正常回收,资源只出不进,导致资源耗尽。

第一种可能性很好验证,调整连接池配置参数`maxActive=500`,观察系统是否健康运行。但调整之后验证失败,500个连接依然迅速耗尽,那基本上确认是连接泄露问题。

首先要定位可能导致连接泄露的代码位置,查看系统运行日志,果然从中找出蛛丝马迹(注:资源使用的异常处理机制非常重要不可或缺,否则大海捞针全靠猜)。

日志中发现ERROR信息:

这个ERROR连续出现N次之后,系统抛出CannotGetJdbcConnectionException,猜测很有可能问题就出现在这里。

`No value for key`的告警信息初始体现在Spring框架TransactionSynchronizationManager的unbindResource方法中,源码如下:

从源码中可以看出,Spring在线程中unbind resource时,发现待处理的key不存在,抛出异常,终止了资源释放处理过程。

Spring的资源释放流程简图如下:

了解了这个过程之后,仔细分析异常日志中的代码行数,发现其中有一行编程式的事务处理代码:

具体为什么写这一行,在这里就不再赘述了。但是因为这个编程式的事务处理逻辑不当,错误的unbind dataSource,导致后续Spring的资源处理过程中(上图第2步)处理失败,无法继续回收数据库连接,连接只能获取不能回收,因此资源池迅速耗尽。

问题基本上已经明确解决,但因此衍生的思考是Spring的事务处理机制原理。

每一次线上问题的处理,都需要深刻理解背后的技术原理,多体验多分析多积累!

本文来自企鹅号 - 全球大搜罗媒体

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文来自企鹅号 - 全球大搜罗媒体

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档