美文网首页
spring事务导致的一次死锁

spring事务导致的一次死锁

作者: ZzzzZzzzz_36b7 | 来源:发表于2019-03-22 18:39 被阅读0次

1,现象简述:

        项目上线,serviceA.methodA()中调用serviceB.methodB(String schoolId)的方法。

        serviceA.methodA()核心业务更新学校信息记录,核心sql:

update table_school set xx=xx where id=xxx;

        serviceB.methodB(String schoolId)核心业务是将学校update记录加入数据库中,将update的信息异步同步给其他服务。再入库之前,要去table_school表中查询所有is_sync=1的学校id,根据此字段判断这个学校是否需要同步。is_sync=0,则不入库。

List<String> schoolIds = schoolDAO.findSchoolIds();  //select id from table_school  where is_sync=1; 

if(!schoolIds.contains(schoolId)){

    continue; //不处理

}

//入库

        结果:在获取schoolIds 时候,程序卡住。所有需要查询table_school表的sql全部阻塞。程序处于不可用状态。

2,分析原因:

        当时通过运维查看数据库进程,了解到:1,数据库阻塞;2,table_school阻塞导致;3通过debug信息定位到具体问题dao,确认问题sql(种种原因,运维无法定位到具体sql)是  select id from table_school  where is_sync=1 。

        最重要的是当时只知道是阻塞。没有信息表明是发生了死锁。而且因为经验不足,数据库性能本身就有问题等各种因素。也没往这个方向考虑。一直怀疑是数据库性能和一些未知的慢sql导致阻塞。(经验不足,考虑方向错的离谱=。=)。

3,解决问题:

        涉及到两个service的方法。查看methodA(),methodB()的事务设置。

        methodA()为PROPAGATION_REQUIRED,timeout_300

        methodB()为PROPAGATION_NOT_SUPPORTED

        这就是问题的关键了,methodA()方法在新建的事务中执行,调用methodB()时,methodB()将methodA()的事务挂起,并且以非事务执行。这样导致methodA()的update school一直没提交,methodB()又去select school,造成了死锁(互斥锁)。因为methodA()的事务被挂起,methodB()没有事务,也不会发生事务超时。日志只能看到很久之后,dbserver close connection 的日志。无法定位程序问题。

        最后将schoolIds 的获取放到methodA()中,并将schoolIds作为参数传入methodB()中解决。

4,总结:

        菜是原罪!

        其实这个问题总的来说,并不复杂。只要能定位到当时数据库发生死锁,查到造成死锁的sql,就能很容易想到互斥锁,查看事务。主要时第一次遇到这种问题,经验不足,真的想不到这层原因。

5 ,收获:

        spring事务传播机制了解的更深了。

        数据库共享锁(s),互斥锁(x)。

        查询数据库死锁,定位死锁sql的方法。

相关文章

  • spring事务导致的一次死锁

    1,现象简述: 项目上线,serviceA.methodA()中调用serviceB.methodB(String...

  • MySQL -- 死锁

    死锁: 死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象,当多个事务...

  • 死锁与MVCC

    死锁 死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象,多个事务同时...

  • 2.Mysql的死锁,及事务日志

    死锁  死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试...

  • spring事务隔离导致数据库连接耗尽而死锁

    记一次压测排查死锁 概述 应用背景 应用是公司内部的基础设施平台,会接收到多个内部平台的数据上报,考虑到后期可能接...

  • 《高性能MySQL》读书摘录之一

    20171108 死锁怎么处理(P10) (如果事务出现死锁)大多数情况下只需要重新执行因死锁回滚的事务即可。 目...

  • InnoDB死锁2

    死锁的产生原因 死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源而导致的恶性循环,因争夺资源而...

  • Kafka事务导致Spring事务不生效

    1. 工程环境 SpringBoot: 2.2.6.RELEASEMybatis-plus: 3.3.0 2. 发...

  • 一次线上死锁问题

    这两天遇到了一个死锁的问题,下面是errorLog打的报错信息 经过网上资料查询,原因为:Spring 事务嵌套造...

  • MySQL死锁分析

    一、表结构,死锁日志,事务隔离级别 表结构: 死锁日志: 事务隔离级别为读已提交。 二、insert on dup...

网友评论

      本文标题:spring事务导致的一次死锁

      本文链接:https://www.haomeiwen.com/subject/nsbrvqtx.html