恰好是我们线上的一个遗留问题。问题的一般情况是我们引入的一个库会导致服务运行一段时间后死锁。并且会导致整个网站无法访问。我们发现可以通过配置库的一些参数来避免死锁,但是会带来一个新的问题,就是事务无法回滚。由于后者的故障级别相对较低,我们先将故障降级,选择优先运行服务。后者是为了调查为什么新的配置会导致事务无法回滚。我负责这件事。从部门同事那里了解了问题的详细情况后,我开始着手调查。首先是梳理问题,梳理新引入的??库与框架的关系和整体运行流程。如果想详细了解整个流程,需要阅读海量代码,不仅需要阅读库,还需要阅读框架源码。就解决问题而言,我觉得还是需要做一个粗略的流程梳理,通过对整个流程的大致了解,然后确定问题的具体位置,再对具体位置进行详细的了解.在粗梳的过程中,我是从新引入的库开始的,主要是库代码比较少,阅读起来也比较快,如果只从库层面解决问题,框架代码也可以略读。对于库源码的理解,我是通过wiki+源码的方式来了解库的整个运行机制,事半功倍。但是,在了解了库的运行机制后,发现问题可能出现在库与框架的配合上。需要涉及框架源码的阅读。在开始阅读框架的源码之前,我决定在本地搭建一个复现环境,通过搭建好的本地环境来调试源码。经过反复调试,最终确定了问题的原因。引入新库后,在事务启动时会创建一个新的数据库连接,通过ORM查询数据库时会创建另一个数据库连接。这样就导致了事务和SQL的执行不在同一个数据库连接中,也就造成了数据库事务无法生效的问题。一旦确定了问题的原因,解决方案就准备好了。我们只需要保证事务和SQL在同一个连接中执行即可。为了解决这个问题,只写了三行代码,既保证了功能的完整性,又不侵入库和框架对底层源码进行改造。这个问题的排查让我想起了福特用10000美元划线的故事。画一条线,$1;知道底线在哪里,$9,999这个问题同时离不开部门的帮助。在调查过程中,我与同事进行了2-3轮沟通。不仅让我对问题有了全面的认识,也给了我几次遇到困惑时解决问题的灵感,包括最终方案制定后的演示,其中蕴含着整个团队的心血。也希望这个调查过程能给大家阅读文章带来一些启发。欢迎您分享您的见解和想法。
