Druid connection holder is null未解之谜

系统中出现过几次connection holder is null问题,有的已解决,有的未解决,记录如下。

首先说先druid连接池的实现:

  • DruidPooledConnection是一个静态代理,持有ConnectionHolder, connection Holder里持有具体的connection对象, 在执行druidPooledConnection的所有和数据库相关方法时,都会先调用checkState()判断connection holder是否为null,如果是null就抛connection holder is null的异常。

  • 那connection holder是什么时候赋值以及什么时候置成null的?
    在Datasource.getConnection()获取连接的时候,是从池里取出缓存的connection holder对象,druid是用一个数组缓存connection holder对象,每次都是从最后一个取,还的时候也是放到最后,这样保证位于数组最后的连接会经常处于使用状态,当然这中间会有锁的使用以及池里没线程了通知任务线程去创建新连接。
    Datasource.getConnection()从池里拿出connection holder后,然后new一个druidPooledConnection去包装connection holder,所有每次看到都是不同的druidPooledConnection对象。

第一次:系统中事务执行时间过长,超过60秒,后面导致有的请求会报connection holder is null。

  • 拿出来的connection holder肯定不为null,项目中报connection holder is null,说明是在使用过程中connection holder被置成null了,很大概率是被别的线程置成null了,因为本线程只有在事务提交后还连接的时候才置null,在github issue上,作者也反复强调连接不要跨线程使用。而druid真的就有跨线程操作连接的地方,就是remove abandoned connection功能,这个功能是为了回收长时间还没还到池里的连接,多长时间看你设置,而我们项目设置的60秒没还就强制回收,这样就会报上面的错误了。

  • 建议在生产环境关闭remove abandoned功能,如果数据库负载不重的话,可以开启testOnBorrow。 testWhileIde不建议开,因为并发请求多的话,数组后面的连接都不是idle状态,开没开testWhileIdle没啥区别。

第二次系统中有的事务长时间未提交,DBA会把这个连接kill掉,后面请求会报conneciton holder is null

  • 为什么有长时间未提交的事务,这个问题还没找到原因,从Mysql的innodb_trx和lock表里没看到有价值线索,后面想跟踪事务和连接来看看有没有收获。
  • 连接被kill了,应用端会报这样的异常:
  1. Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
  2. com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure. The last packet successfully received from the server was 20,840 milliseconds ago. The last packet sent successfully to the server was 20,840 milliseconds ago.
  3. connection holder is null

前面2个异常很好理解,tcp连接断了,应用端读不到数据报错,然后druid捕获到异常,要去判断这个异常是可恢复异常还是不可恢复异常。因为站在连接池的角度来说,数据库抛异常太普遍了,可能是唯一索引重复也可能是连接断了,对于不同的异常处理方式也是不一样的,唯一索引重复需要调用connection.rollback(),然后再把连接还到池里,因为这个连接还是好的,不影响下次继续使用。而连接断了,则要把这个连接踢出去,druid用了ExceptionSorter来判断这个异常是不是不可恢复异常,在转换异常的时候要用当前连接获取数据库的metadata,而当前连接已经断了,所以报connection holder is null。
但是这个connection holder is null只会报一次,和项目中大量报connection holder is null不是一个东西,目前还没找到原因。而这个问题在本地却重现不了。

PS:数据库有一个设置 rollback_on_timeout,默认是off,这个值是说当事务超时(如超过50秒还没获取到锁),默认off是回滚最后一条sql语句,on是回滚整个事务。这个值一般不需要设置成on,交由应用去处理,应用在获取不到 can't acquire lock的时候,一般会去调connection.rollback(),当然前提是要你的应用开启事务。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容