从上面表中、发现两个线程在同时申请同一行数据的锁,但令人疑惑的是,无论是多个线程请求同一把锁,这个不构成死锁的条件,那为什么会出现无法获取锁的情况呢?为了进一步确认数据锁的情况,然后尝试用 show engine innodb status;查看一下Innodb当前的状态信息:
从这里也能看出,数据库层面目前有两个锁请求(等待),还是构成不了死锁。
这个时候,我们从数据库层面已经获取到足够的信息,就是这条语句正在尝试获取锁,但锁已经被占用。
该SQL 使用了 select … for update语句,该锁在什么时候会释放呢?事务提交或事务回滚时自动释放?难不成是在业务层事务提交或回滚有问题,但平时使用正常呀,故暂时应该可以排查业务层的事务控制部分的bug,接下来我们应该重点,从SQL语句去跟踪代码,梳理整个业务流程,业务层为什么没有结束。
2)业务层代码排查
排查思路:
首先根据sql,找到dao层的方法,然后看dao层方法的调用链。
然后根据代码跟踪,发现该方法只在一个方法中被调用:
该方法(amethod1)的伪代码为:
获取ZK锁(uid) --