동료가 작성한 코드로 인해 데이터베이스가 교착 상태에 빠졌습니다.

배경

새로운 프로젝트가 곧 온라인으로 전환 될 예정입니다. 기능을 테스트 할 때 버튼을 클릭 한 후 페이지가 멈췄다는 것을 발견했습니다. 처음에는 네트워크 문제라고 생각했지만 페이지가 멈춰 100 % 재현되었습니다. 백그라운드 로그를 확인하고 업데이트 문을 실행하는 동안 잠겨 있음을 확인했습니다.

영상

SQL을 통한 쿼리

select * from information_schema.innodb_trx;

sys_sn_rule 테이블을 업데이트하여 발생한 것으로 확인되었으므로 코드를 정렬하고 LOCK_WAIT가 나타나는 이유를 살펴 보겠습니다.

원인 조사

인터페이스 호출을보고 메서드를 찾습니다. 여기서 메서드를 단순화합니다. 단순화 된 코드는 다음과 같습니다.

@Override
@Transactional(rollbackFor = Exception.class)
public Result funA() {
    //更新表table1;
    funB();
    ...
}

public void funB() {
   //更新表table1;
   ....
}

문제는 funA가 funB를 호출하고 두 메서드가 table1의 동일한 데이터에 대해 동시에 작동한다는 것입니다. 여기에는 두 개의 트랜잭션이 있으며 데이터가 업데이트되면 두 트랜잭션이 서로 트랜잭션을 닫을 때까지 대기하게되며 이때 교착 상태가됩니다. 그림으로 설명해 봅시다 :

영상

교착 상태 다이어그램

위의 그림과 같이 funA가 실행되면 테이블 1이 업데이트되고 테이블이 업데이트되기 전에 트랜잭션 A가 열리고 테이블이 업데이트 될 때이 데이터 행이 잠 깁니다 (데이터 일관성을 보호하기 위해). . 그런 다음 funB를 호출하고 트랜잭션 B를 열고 table1 테이블을 업데이트합니다. table1의 행이 잠겨 있으므로 트랜잭션 B는 잠금이 해제 될 때까지 기다려야 계속 진행할 수 있습니다. 그러나 트랜잭션 A를 닫으려면 funA가 실행을 마칠 때까지 기다려야 닫힐 수 있습니다. FunB는 funA에서 호출되고 funB는 실행되기 전에 table1이 잠금을 해제 할 때까지 기다려야합니다. 이것은 무한 루프로 이어집니다.

데이터베이스 잠금에 대한 지식은 다음 기사를 읽을 수 있습니다.

교착 상태 학습 트랜잭션 및 격리 수준을 해결하는 길 -aneasystone의 블로그

(https://www.aneasystone.com/archives/2017/10/solving-dead-locks-one.html)

해결책

멀티 스레딩을 사용하여 다음을 해결할 수 있습니다.

@Override
@Transactional(rollbackFor = Exception.class)
public Result funA() {
    //更新表table1;
    taskExecutor.execute(() -> {
        try {
            Thread.sleep(5 * 1000);
            funB();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    ...
}

public void funB() {
   //更新表table1;
   ....
}

멀티 스레딩을 사용하면 두 트랜잭션이 두 개의 서로 다른 스레드에 있으며 대기중인 루프가 없습니다.

영상

교착 상태 다이어그램-멀티 스레딩

코드가 수정 된 후 테스트는 순조롭게 통과되었습니다.

과거에 추천

QR 코드를 스캔하여 더 흥미 진진하게 만드세요. 또는 WeChat 에서 Lvshen_9를 검색 하여 답장하여 백그라운드에서 정보를 얻을 수 있습니다.

  1. 回复"java" 获取java电子书;

  2. 回复"python"获取python电子书;

  3. 回复"算法"获取算法电子书;

  4. 回复"大数据"获取大数据电子书;

  5. 回复"spring"获取SpringBoot的学习视频。

  6. 回复"面试"获取一线大厂面试资料

  7. 回复"进阶之路"获取Java进阶之路的思维导图

  8. 回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

  9. 回复"总结"获取Java后端面试经验总结PDF版

  10. 回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

  11. 回复"并发导图"获取Java并发编程思维导图(xmind终极版)

기타 : 더 많은 놀라움을 얻으 려면 [ 내 혜택 ]을 클릭하십시오 .

추천

출처blog.csdn.net/wujialv/article/details/113392118